COMPLETE.T
资源名称:os_source.zip [点击查看]
上传用户:datang2001
上传日期:2007-02-01
资源大小:53269k
文件大小:2535k
源码类别:
操作系统开发
开发平台:
C/C++
- 15627 case 0: /* Clear from cursor to end of line */
- 15628 count = scr_width - cons->c_column;
- 15629 dst = cons->c_cur;
- 15630 break;
- 15631 case 1: /* Clear from beginning of line to cursor */
- 15632 count = cons->c_column;
- 15633 dst = cons->c_cur - cons->c_column;
- 15634 break;
- 15635 case 2: /* Clear entire line */
- 15636 count = scr_width;
- 15637 dst = cons->c_cur - cons->c_column;
- 15638 break;
- 15639 default: /* Do nothing */
- 15640 count = 0;
- 15641 dst = cons->c_cur;
- 15642 }
- 15643 blank_color = cons->c_blank;
- 15644 mem_vid_copy(BLANK_MEM, dst, count);
- 15645 break;
- 15646
- 15647 case 'L': /* ESC [nL inserts n lines at cursor */
- 15648 n = value;
- 15649 if (n < 1) n = 1;
- 15650 if (n > (scr_lines - cons->c_row))
- 15651 n = scr_lines - cons->c_row;
- 15652
- 15653 src = cons->c_org + cons->c_row * scr_width;
- 15654 dst = src + n * scr_width;
- 15655 count = (scr_lines - cons->c_row - n) * scr_width;
- 15656 vid_vid_copy(src, dst, count);
- 15657 blank_color = cons->c_blank;
- 15658 mem_vid_copy(BLANK_MEM, src, n * scr_width);
- 15659 break;
- .Ep 198 src/kernel/console.c
- 15660
- 15661 case 'M': /* ESC [nM deletes n lines at cursor */
- 15662 n = value;
- 15663 if (n < 1) n = 1;
- 15664 if (n > (scr_lines - cons->c_row))
- 15665 n = scr_lines - cons->c_row;
- 15666
- 15667 dst = cons->c_org + cons->c_row * scr_width;
- 15668 src = dst + n * scr_width;
- 15669 count = (scr_lines - cons->c_row - n) * scr_width;
- 15670 vid_vid_copy(src, dst, count);
- 15671 blank_color = cons->c_blank;
- 15672 mem_vid_copy(BLANK_MEM, dst + count, n * scr_width);
- 15673 break;
- 15674
- 15675 case '@': /* ESC [n@ inserts n chars at cursor */
- 15676 n = value;
- 15677 if (n < 1) n = 1;
- 15678 if (n > (scr_width - cons->c_column))
- 15679 n = scr_width - cons->c_column;
- 15680
- 15681 src = cons->c_cur;
- 15682 dst = src + n;
- 15683 count = scr_width - cons->c_column - n;
- 15684 vid_vid_copy(src, dst, count);
- 15685 blank_color = cons->c_blank;
- 15686 mem_vid_copy(BLANK_MEM, src, n);
- 15687 break;
- 15688
- 15689 case 'P': /* ESC [nP deletes n chars at cursor */
- 15690 n = value;
- 15691 if (n < 1) n = 1;
- 15692 if (n > (scr_width - cons->c_column))
- 15693 n = scr_width - cons->c_column;
- 15694
- 15695 dst = cons->c_cur;
- 15696 src = dst + n;
- 15697 count = scr_width - cons->c_column - n;
- 15698 vid_vid_copy(src, dst, count);
- 15699 blank_color = cons->c_blank;
- 15700 mem_vid_copy(BLANK_MEM, dst + count, n);
- 15701 break;
- 15702
- 15703 case 'm': /* ESC [nm enables rendition n */
- 15704 switch (value) {
- 15705 case 1: /* BOLD */
- 15706 if (color) {
- 15707 /* Can't do bold, so use yellow */
- 15708 cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0E00;
- 15709 } else {
- 15710 /* Set intensity bit */
- 15711 cons->c_attr |= 0x0800;
- 15712 }
- 15713 break;
- 15714
- 15715 case 4: /* UNDERLINE */
- 15716 if (color) {
- 15717 /* Use light green */
- 15718 cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0A00;
- 15719 } else {
- .Op 199 src/kernel/console.c
- 15720 cons->c_attr = (cons->c_attr & 0x8900);
- 15721 }
- 15722 break;
- 15723
- 15724 case 5: /* BLINKING */
- 15725 if (color) {
- 15726 /* Use magenta */
- 15727 cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0500;
- 15728 } else {
- 15729 /* Set the blink bit */
- 15730 cons->c_attr |= 0x8000;
- 15731 }
- 15732 break;
- 15733
- 15734 case 7: /* REVERSE */
- 15735 if (color) {
- 15736 /* Swap fg and bg colors */
- 15737 cons->c_attr =
- 15738 ((cons->c_attr & 0xf000) >> 4) |
- 15739 ((cons->c_attr & 0x0f00) << 4);
- 15740 } else
- 15741 if ((cons->c_attr & 0x7000) == 0) {
- 15742 cons->c_attr = (cons->c_attr & 0x8800) | 0x7000;
- 15743 } else {
- 15744 cons->c_attr = (cons->c_attr & 0x8800) | 0x0700;
- 15745 }
- 15746 break;
- 15747
- 15748 default: /* COLOR */
- 15749 if (30 <= value && value <= 37) {
- 15750 cons->c_attr =
- 15751 (cons->c_attr & 0xf0ff) |
- 15752 (ansi_colors[(value - 30)] << 8);
- 15753 cons->c_blank =
- 15754 (cons->c_blank & 0xf0ff) |
- 15755 (ansi_colors[(value - 30)] << 8);
- 15756 } else
- 15757 if (40 <= value && value <= 47) {
- 15758 cons->c_attr =
- 15759 (cons->c_attr & 0x0fff) |
- 15760 (ansi_colors[(value - 40)] << 12);
- 15761 cons->c_blank =
- 15762 (cons->c_blank & 0x0fff) |
- 15763 (ansi_colors[(value - 40)] << 12);
- 15764 } else {
- 15765 cons->c_attr = cons->c_blank;
- 15766 }
- 15767 break;
- 15768 }
- 15769 break;
- 15770 }
- 15771 }
- 15772 cons->c_esc_state = 0;
- 15773 }
- 15776 /*===========================================================================*
- 15777 * set_6845 *
- 15778 *===========================================================================*/
- 15779 PRIVATE void set_6845(reg, val)
- .Ep 200 src/kernel/console.c
- 15780 int reg; /* which register pair to set */
- 15781 unsigned val; /* 16-bit value to set it to */
- 15782 {
- 15783 /* Set a register pair inside the 6845.
- 15784 * Registers 12-13 tell the 6845 where in video ram to start
- 15785 * Registers 14-15 tell the 6845 where to put the cursor
- 15786 */
- 15787 lock(); /* try to stop h/w loading in-between value */
- 15788 out_byte(vid_port + INDEX, reg); /* set the index register */
- 15789 out_byte(vid_port + DATA, (val>>8) & BYTE); /* output high byte */
- 15790 out_byte(vid_port + INDEX, reg + 1); /* again */
- 15791 out_byte(vid_port + DATA, val&BYTE); /* output low byte */
- 15792 unlock();
- 15793 }
- 15796 /*===========================================================================*
- 15797 * beep *
- 15798 *===========================================================================*/
- 15799 PRIVATE void beep()
- 15800 {
- 15801 /* Making a beeping sound on the speaker (output for CRTL-G).
- 15802 * This routine works by turning on the bits 0 and 1 in port B of the 8255
- 15803 * chip that drive the speaker.
- 15804 */
- 15805
- 15806 message mess;
- 15807
- 15808 if (beeping) return;
- 15809 out_byte(TIMER_MODE, 0xB6); /* set up timer channel 2 (square wave) */
- 15810 out_byte(TIMER2, BEEP_FREQ & BYTE); /* load low-order bits of frequency */
- 15811 out_byte(TIMER2, (BEEP_FREQ >> 8) & BYTE); /* now high-order bits */
- 15812 lock(); /* guard PORT_B from keyboard intr handler */
- 15813 out_byte(PORT_B, in_byte(PORT_B) | 3); /* turn on beep bits */
- 15814 unlock();
- 15815 beeping = TRUE;
- 15816
- 15817 mess.m_type = SET_ALARM;
- 15818 mess.CLOCK_PROC_NR = TTY;
- 15819 mess.DELTA_TICKS = B_TIME;
- 15820 mess.FUNC_TO_CALL = (sighandler_t) stop_beep;
- 15821 sendrec(CLOCK, &mess);
- 15822 }
- 15825 /*===========================================================================*
- 15826 * stop_beep *
- 15827 *===========================================================================*/
- 15828 PRIVATE void stop_beep()
- 15829 {
- 15830 /* Turn off the beeper by turning off bits 0 and 1 in PORT_B. */
- 15831
- 15832 lock(); /* guard PORT_B from keyboard intr handler */
- 15833 out_byte(PORT_B, in_byte(PORT_B) & ~3);
- 15834 beeping = FALSE;
- 15835 unlock();
- 15836 }
- 15839 /*===========================================================================*
- .Op 201 src/kernel/console.c
- 15840 * scr_init *
- 15841 *===========================================================================*/
- 15842 PUBLIC void scr_init(tp)
- 15843 tty_t *tp;
- 15844 {
- 15845 /* Initialize the screen driver. */
- 15846 console_t *cons;
- 15847 phys_bytes vid_base;
- 15848 u16_t bios_crtbase;
- 15849 int line;
- 15850 unsigned page_size;
- 15851
- 15852 /* Associate console and TTY. */
- 15853 line = tp - &tty_table[0];
- 15854 if (line >= nr_cons) return;
- 15855 cons = &cons_table[line];
- 15856 cons->c_tty = tp;
- 15857 tp->tty_priv = cons;
- 15858
- 15859 /* Initialize the keyboard driver. */
- 15860 kb_init(tp);
- 15861
- 15862 /* Output functions. */
- 15863 tp->tty_devwrite = cons_write;
- 15864 tp->tty_echo = cons_echo;
- 15865
- 15866 /* Get the BIOS parameters that tells the VDU I/O base register. */
- 15867 phys_copy(0x463L, vir2phys(&bios_crtbase), 2L);
- 15868
- 15869 vid_port = bios_crtbase;
- 15870
- 15871 if (color) {
- 15872 vid_base = COLOR_BASE;
- 15873 vid_size = COLOR_SIZE;
- 15874 } else {
- 15875 vid_base = MONO_BASE;
- 15876 vid_size = MONO_SIZE;
- 15877 }
- 15878 if (ega) vid_size = EGA_SIZE;
- 15879 wrap = !ega;
- 15880
- 15881 vid_seg = protected_mode ? VIDEO_SELECTOR : physb_to_hclick(vid_base);
- 15882 init_dataseg(&gdt[VIDEO_INDEX], vid_base, (phys_bytes) vid_size,
- 15883 TASK_PRIVILEGE);
- 15884 vid_size >>= 1; /* word count */
- 15885 vid_mask = vid_size - 1;
- 15886
- 15887 /* There can be as many consoles as video memory allows. */
- 15888 nr_cons = vid_size / scr_size;
- 15889 if (nr_cons > NR_CONS) nr_cons = NR_CONS;
- 15890 if (nr_cons > 1) wrap = 0;
- 15891 page_size = vid_size / nr_cons;
- 15892 cons->c_start = line * page_size;
- 15893 cons->c_limit = cons->c_start + page_size;
- 15894 cons->c_org = cons->c_start;
- 15895 cons->c_attr = cons->c_blank = BLANK_COLOR;
- 15896
- 15897 /* Clear the screen. */
- 15898 blank_color = BLANK_COLOR;
- 15899 mem_vid_copy(BLANK_MEM, cons->c_start, scr_size);
- .Ep 202 src/kernel/console.c
- 15900 select_console(0);
- 15901 }
- 15904 /*===========================================================================*
- 15905 * putk *
- 15906 *===========================================================================*/
- 15907 PUBLIC void putk(c)
- 15908 int c; /* character to print */
- 15909 {
- 15910 /* This procedure is used by the version of printf() that is linked with
- 15911 * the kernel itself. The one in the library sends a message to FS, which is
- 15912 * not what is needed for printing within the kernel. This version just queues
- 15913 * the character and starts the output.
- 15914 */
- 15915
- 15916 if (c != 0) {
- 15917 if (c == 'n') putk('r');
- 15918 out_char(&cons_table[0], (int) c);
- 15919 } else {
- 15920 flush(&cons_table[0]);
- 15921 }
- 15922 }
- 15925 /*===========================================================================*
- 15926 * toggle_scroll *
- 15927 *===========================================================================*/
- 15928 PUBLIC void toggle_scroll()
- 15929 {
- 15930 /* Toggle between hardware and software scroll. */
- 15931
- 15932 cons_org0();
- 15933 softscroll = !softscroll;
- 15934 printf("%sware scrolling enabled.n", softscroll ? "Soft" : "Hard");
- 15935 }
- 15938 /*===========================================================================*
- 15939 * cons_stop *
- 15940 *===========================================================================*/
- 15941 PUBLIC void cons_stop()
- 15942 {
- 15943 /* Prepare for halt or reboot. */
- 15944 cons_org0();
- 15945 softscroll = 1;
- 15946 select_console(0);
- 15947 cons_table[0].c_attr = cons_table[0].c_blank = BLANK_COLOR;
- 15948 }
- 15951 /*===========================================================================*
- 15952 * cons_org0 *
- 15953 *===========================================================================*/
- 15954 PRIVATE void cons_org0()
- 15955 {
- 15956 /* Scroll video memory back to put the origin at 0. */
- 15957 int cons_line;
- 15958 console_t *cons;
- 15959 unsigned n;
- .Op 203 src/kernel/console.c
- 15960
- 15961 for (cons_line = 0; cons_line < nr_cons; cons_line++) {
- 15962 cons = &cons_table[cons_line];
- 15963 while (cons->c_org > cons->c_start) {
- 15964 n = vid_size - scr_size; /* amount of unused memory */
- 15965 if (n > cons->c_org - cons->c_start)
- 15966 n = cons->c_org - cons->c_start;
- 15967 vid_vid_copy(cons->c_org, cons->c_org - n, scr_size);
- 15968 cons->c_org -= n;
- 15969 }
- 15970 flush(cons);
- 15971 }
- 15972 select_console(current);
- 15973 }
- 15976 /*===========================================================================*
- 15977 * select_console *
- 15978 *===========================================================================*/
- 15979 PUBLIC void select_console(int cons_line)
- 15980 {
- 15981 /* Set the current console to console number 'cons_line'. */
- 15982
- 15983 if (cons_line < 0 || cons_line >= nr_cons) return;
- 15984 current = cons_line;
- 15985 curcons = &cons_table[cons_line];
- 15986 set_6845(VID_ORG, curcons->c_org);
- 15987 set_6845(CURSOR, curcons->c_cur);
- 15988 }
- 15991 /*===========================================================================*
- 15992 * con_loadfont *
- 15993 *===========================================================================*/
- 15994
- 15995 PUBLIC int con_loadfont(user_phys)
- 15996 phys_bytes user_phys;
- 15997 {
- 15998 /* Load a font into the EGA or VGA adapter. */
- 15999 static struct sequence seq1[7] = {
- 16000 { GA_SEQUENCER_INDEX, 0x00, 0x01 },
- 16001 { GA_SEQUENCER_INDEX, 0x02, 0x04 },
- 16002 { GA_SEQUENCER_INDEX, 0x04, 0x07 },
- 16003 { GA_SEQUENCER_INDEX, 0x00, 0x03 },
- 16004 { GA_GRAPHICS_INDEX, 0x04, 0x02 },
- 16005 { GA_GRAPHICS_INDEX, 0x05, 0x00 },
- 16006 { GA_GRAPHICS_INDEX, 0x06, 0x00 },
- 16007 };
- 16008 static struct sequence seq2[7] = {
- 16009 { GA_SEQUENCER_INDEX, 0x00, 0x01 },
- 16010 { GA_SEQUENCER_INDEX, 0x02, 0x03 },
- 16011 { GA_SEQUENCER_INDEX, 0x04, 0x03 },
- 16012 { GA_SEQUENCER_INDEX, 0x00, 0x03 },
- 16013 { GA_GRAPHICS_INDEX, 0x04, 0x00 },
- 16014 { GA_GRAPHICS_INDEX, 0x05, 0x10 },
- 16015 { GA_GRAPHICS_INDEX, 0x06, 0 },
- 16016 };
- 16017
- 16018 seq2[6].value= color ? 0x0E : 0x0A;
- 16019
- .Ep 204 src/kernel/console.c
- 16020 if (!ega) return(ENOTTY);
- 16021
- 16022 lock();
- 16023 ga_program(seq1); /* bring font memory into view */
- 16024
- 16025 phys_copy(user_phys, (phys_bytes)GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);
- 16026
- 16027 ga_program(seq2); /* restore */
- 16028 unlock();
- 16029
- 16030 return(OK);
- 16031 }
- 16034 /*===========================================================================*
- 16035 * ga_program *
- 16036 *===========================================================================*/
- 16037
- 16038 PRIVATE void ga_program(seq)
- 16039 struct sequence *seq;
- 16040 {
- 16041 int len= 7;
- 16042 do {
- 16043 out_byte(seq->index, seq->port);
- 16044 out_byte(seq->index+1, seq->value);
- 16045 seq++;
- 16046 } while (--len > 0);
- 16047 }
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- src/kernel/dmp.c
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 16100 /* This file contains some dumping routines for debugging. */
- 16101
- 16102 #include "kernel.h"
- 16103 #include <minix/com.h>
- 16104 #include "proc.h"
- 16105
- 16106 char *vargv;
- 16107
- 16108 FORWARD _PROTOTYPE(char *proc_name, (int proc_nr));
- 16109
- 16110 /*===========================================================================*
- 16111 * p_dmp *
- 16112 *===========================================================================*/
- 16113 #if (CHIP == INTEL)
- 16114 PUBLIC void p_dmp()
- 16115 {
- 16116 /* Proc table dump */
- 16117
- 16118 register struct proc *rp;
- 16119 static struct proc *oldrp = BEG_PROC_ADDR;
- 16120 int n = 0;
- 16121 phys_clicks text, data, size;
- 16122 int proc_nr;
- 16123
- 16124 printf("n--pid --pc- ---sp- flag -user --sys-- -text- -data- -size- -recv- commandn");
- .Op 205 src/kernel/dmp.c
- 16125
- 16126 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
- 16127 proc_nr = proc_number(rp);
- 16128 if (rp->p_flags & P_SLOT_FREE) continue;
- 16129 if (++n > 20) break;
- 16130 text = rp->p_map[T].mem_phys;
- 16131 data = rp->p_map[D].mem_phys;
- 16132 size = rp->p_map[T].mem_len
- 16133 + ((rp->p_map[S].mem_phys + rp->p_map[S].mem_len) - data);
- 16134 printf("%5d %5lx %6lx %2x %7U %7U %5uK %5uK %5uK ",
- 16135 proc_nr < 0 ? proc_nr : rp->p_pid,
- 16136 (unsigned long) rp->p_reg.pc,
- 16137 (unsigned long) rp->p_reg.sp,
- 16138 rp->p_flags,
- 16139 rp->user_time, rp->sys_time,
- 16140 click_to_round_k(text), click_to_round_k(data),
- 16141 click_to_round_k(size));
- 16142 if (rp->p_flags & RECEIVING) {
- 16143 printf("%-7.7s", proc_name(rp->p_getfrom));
- 16144 } else
- 16145 if (rp->p_flags & SENDING) {
- 16146 printf("S:%-5.5s", proc_name(rp->p_sendto));
- 16147 } else
- 16148 if (rp->p_flags == 0) {
- 16149 printf(" ");
- 16150 }
- 16151 printf("%sn", rp->p_name);
- 16152 }
- 16153 if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--r");
- 16154 oldrp = rp;
- 16155 }
- 16156 #endif /* (CHIP == INTEL) */
- 16157
- 16158 /*===========================================================================*
- 16159 * map_dmp *
- 16160 *===========================================================================*/
- 16161 #if (SHADOWING == 0)
- 16162 PUBLIC void map_dmp()
- 16163 {
- 16164 register struct proc *rp;
- 16165 static struct proc *oldrp = cproc_addr(HARDWARE);
- 16166 int n = 0;
- 16167 phys_clicks size;
- 16168
- 16169 printf("nPROC NAME- -----TEXT----- -----DATA----- ----STACK----- -SIZE-n");
- 16170 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
- 16171 if (rp->p_flags & P_SLOT_FREE) continue;
- 16172 if (++n > 20) break;
- 16173 size = rp->p_map[T].mem_len
- 16174 + ((rp->p_map[S].mem_phys + rp->p_map[S].mem_len)
- 16175 - rp->p_map[D].mem_phys);
- 16176 printf("%3d %-6.6s %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uKn",
- 16177 proc_number(rp),
- 16178 rp->p_name,
- 16179 rp->p_map[T].mem_vir, rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
- 16180 rp->p_map[D].mem_vir, rp->p_map[D].mem_phys, rp->p_map[D].mem_len,
- 16181 rp->p_map[S].mem_vir, rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
- 16182 click_to_round_k(size));
- 16183 }
- 16184 if (rp == END_PROC_ADDR) rp = cproc_addr(HARDWARE); else printf("--more--r");
- .Ep 206 src/kernel/dmp.c
- 16185 oldrp = rp;
- 16186 }
- 16188 #else
- 16189
- 16190 PUBLIC void map_dmp()
- 16191 {
- 16192 register struct proc *rp;
- 16193 static struct proc *oldrp = cproc_addr(HARDWARE);
- 16194 int n = 0;
- 16195 vir_clicks base, limit;
- 16196
- 16197 printf("nPROC NAME- --TEXT--- --DATA--- --STACK-- SHADOW FLIP P BASE SIZEn");
- 16198 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
- 16199 if (rp->p_flags & P_SLOT_FREE) continue;
- 16200 if (++n > 20) break;
- 16201 base = rp->p_map[T].mem_phys;
- 16202 limit = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
- 16203 printf("%3d %-6.6s %4x %4x %4x %4x %4x %4x %4x %4d %d %4uKn",
- 16204 proc_number(rp),
- 16205 rp->p_name,
- 16206 rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
- 16207 rp->p_map[D].mem_phys, rp->p_map[D].mem_len,
- 16208 rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
- 16209 rp->p_shadow, rp->p_nflips, rp->p_physio,
- 16210 click_to_round_k(base), click_to_round_k(limit));
- 16211 }
- 16212 if (rp == END_PROC_ADDR) rp = cproc_addr(HARDWARE); else printf("--more--r");
- 16213 oldrp = rp;
- 16214 }
- 16216 #endif
- 16217
- 16218 #if (CHIP == M68000)
- 16219 FORWARD _PROTOTYPE(void mem_dmp, (char *adr, int len));
- 16220
- 16221 /*===========================================================================*
- 16222 * p_dmp *
- 16223 *===========================================================================*/
- 16224 PUBLIC void p_dmp()
- 16225 {
- 16226 /* Proc table dump */
- 16227
- 16228 register struct proc *rp;
- 16229 static struct proc *oldrp = BEG_PROC_ADDR;
- 16230 int n = 0;
- 16231 vir_clicks base, limit;
- 16232
- 16233 printf(
- 16234 "nproc pid pc sp splow flag user sys recv commandn");
- 16235
- 16236 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
- 16237 if (rp->p_flags & P_SLOT_FREE) continue;
- 16238 if (++n > 20) break;
- 16239 base = rp->p_map[T].mem_phys;
- 16240 limit = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
- 16241 printf("%4u %4u %6lx %6lx %6lx %4x %5U %6U ",
- 16242 proc_number(rp),
- 16243 rp->p_pid,
- 16244 (unsigned long) rp->p_reg.pc,
- .Op 207 src/kernel/dmp.c
- 16245 (unsigned long) rp->p_reg.sp,
- 16246 (unsigned long) rp->p_splow,
- 16247 rp->p_flags,
- 16248 rp->user_time, rp->sys_time);
- 16249 if (rp->p_flags & RECEIVING) {
- 16250 printf("%-7.7s", proc_name(rp->p_getfrom));
- 16251 } else
- 16252 if (rp->p_flags & SENDING) {
- 16253 printf("S:%-5.5s", proc_name(rp->p_sendto));
- 16254 } else
- 16255 if (rp->p_flags == 0) {
- 16256 printf(" ");
- 16257 }
- 16258 printf("%sn", rp->p_name);
- 16259 }
- 16260 if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--r");
- 16261 oldrp = rp;
- 16262 }
- 16265 /*===========================================================================*
- 16266 * reg_dmp *
- 16267 *===========================================================================*/
- 16268 PUBLIC void reg_dmp(rp)
- 16269 struct proc *rp;
- 16270 {
- 16271 register int i;
- 16272 static char *regs[NR_REGS] = {
- 16273 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
- 16274 "a0", "a1", "a2", "a3", "a4", "a5", "a6"
- 16275 };
- 16276 reg_t *regptr = (reg_t *) & rp->p_reg;
- 16277
- 16278 printf("reg = %08lx, ", rp);
- 16279 printf("ksp = %08lxn", (long) &rp + sizeof(rp));
- 16280 printf(" pc = %08lx, ", rp->p_reg.pc);
- 16281 printf(" sr = %04x, ", rp->p_reg.psw);
- 16282 printf("trp = %2xn", rp->p_trap);
- 16283 for (i = 0; i < NR_REGS; i++)
- 16284 printf("%3s = %08lx%s",regs[i], *regptr++, (i&3) == 3 ? "n" : ", ");
- 16285 printf(" a7 = %08lxn", rp->p_reg.sp);
- 16286 #if (SHADOWING == 1)
- 16287 mem_dmp((char *) (((long) rp->p_reg.pc & ~31L) - 96), 128);
- 16288 mem_dmp((char *) (((long) rp->p_reg.sp & ~31L) - 32), 256);
- 16289 #else
- 16290 mem_dmp((char *) (((long) rp->p_reg.pc & ~31L) - 96 +
- 16291 ((long)rp->p_map[T].mem_phys<<CLICK_SHIFT)), 128);
- 16292 mem_dmp((char *) (((long) rp->p_reg.sp & ~31L) - 32 +
- 16293 ((long)rp->p_map[S].mem_phys<<CLICK_SHIFT)), 256);
- 16294 #endif
- 16295 }
- 16298 /*===========================================================================*
- 16299 * mem_dmp *
- 16300 *===========================================================================*/
- 16301 PRIVATE void mem_dmp(adr, len)
- 16302 char *adr;
- 16303 int len;
- 16304 {
- .Ep 208 src/kernel/dmp.c
- 16305 register i;
- 16306 register long *p;
- 16307
- 16308 for (i = 0, p = (long *) adr; i < len; i += 4) {
- 16309 #if (CHIP == M68000)
- 16310 if ((i & 31) == 0) printf("n%lX:", p);
- 16311 printf(" %8lX", *p++);
- 16312 #else
- 16313 if ((i & 31) == 0) printf("n%X:", p);
- 16314 printf(" %8X", *p++);
- 16315 #endif /* (CHIP == M68000) */
- 16316 }
- 16317 printf("n");
- 16318 }
- 16320 #endif /* (CHIP == M68000) */
- 16321
- 16322
- 16323 /*===========================================================================*
- 16324 * proc_name *
- 16325 *===========================================================================*/
- 16326 PRIVATE char *proc_name(proc_nr)
- 16327 int proc_nr;
- 16328 {
- 16329 if (proc_nr == ANY) return "ANY";
- 16330 return proc_addr(proc_nr)->p_name;
- 16331 }
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- src/kernel/dp8390.c
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 16400 /*
- 16401 * dp8390.c
- 16402 *
- 16403 * This file contains a ethernet device driver for NS dp8390 based ethernet
- 16404 * cards.
- 16405 *
- 16406 * The valid messages and their parameters are:
- 16407 *
- 16408 * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
- 16409 * |------------+----------+---------+----------+---------+---------|
- 16410 * | HARDINT | | | | | |
- 16411 * |------------|----------|---------|----------|---------|---------|
- 16412 * | DL_WRITE | port nr | proc nr | count | mode | address |
- 16413 * |------------|----------|---------|----------|---------|---------|
- 16414 * | DL_WRITEV | port nr | proc nr | count | mode | address |
- 16415 * |------------|----------|---------|----------|---------|---------|
- 16416 * | DL_READ | port nr | proc nr | count | | address |
- 16417 * |------------|----------|---------|----------|---------|---------|
- 16418 * | DL_READV | port nr | proc nr | count | | address |
- 16419 * |------------|----------|---------|----------|---------|---------|
- 16420 * | DL_INIT | port nr | proc nr | mode | | address |
- 16421 * |------------|----------|---------|----------|---------|---------|
- 16422 * | DL_GETSTAT | port nr | proc nr | | | address |
- 16423 * |------------|----------|---------|----------|---------|---------|
- 16424 * | DL_STOP | port_nr | | | | |
- .Op 209 src/kernel/dp8390.c
- 16425 * |------------|----------|---------|----------|---------|---------|
- 16426 *
- 16427 * The messages sent are:
- 16428 *
- 16429 * m-type DL_POR T DL_PROC DL_COUNT DL_STAT DL_CLCK
- 16430 * |------------|----------|---------|----------|---------|---------|
- 16431 * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
- 16432 * |------------|----------|---------|----------|---------|---------|
- 16433 *
- 16434 * m_type m3_i1 m3_i2 m3_ca1
- 16435 * |------------+---------+-----------+---------------|
- 16436 * |DL_INIT_REPL| port nr | last port | ethernet addr |
- 16437 * |------------|---------|-----------|---------------|
- 16438 *
- 16439 * Created: before Dec 28, 1992 by Philip Homburg <philip@cs.vu.nl>
- 16440 *
- 16441 * Modified to become a generic dp8390 driver.
- 16442 * March 10, 1994, Philip Homburg
- 16443 */
- 16444
- 16445 #include "kernel.h"
- 16446 #include <stdlib.h>
- 16447 #include <minix/com.h>
- 16448 #include <net/hton.h>
- 16449 #include <net/gen/ether.h>
- 16450 #include <net/gen/eth_io.h>
- 16451 #include "assert.h"
- 16452 INIT_ASSERT
- 16453 #include "protect.h"
- 16454 #include "dp8390.h"
- 16455 #include "proc.h"
- 16456
- 16457 #if ENABLE_NETWORKING
- 16458
- 16459 #if !__minix_vmd
- 16460 #define printW() (void) 0
- 16461 #define debug 0
- 16462 #endif
- 16463
- 16464 #define DE_PORT_NR 2
- 16465
- 16466 static dpeth_t de_table[DE_PORT_NR];
- 16467 static int int_pending[NR_IRQ_VECTORS];
- 16468 static int dpeth_tasknr= ANY;
- 16469 static u16_t eth_ign_proto;
- 16470
- 16471 /* Configuration */
- 16472 typedef struct dp_conf
- 16473 {
- 16474 port_t dpc_port;
- 16475 int dpc_irq;
- 16476 phys_bytes dpc_mem;
- 16477 char *dpc_envvar;
- 16478 segm_t dpc_prot_sel;
- 16479 } dp_conf_t;
- 16480
- 16481 dp_conf_t dp_conf[]= /* Card addresses */
- 16482 {
- 16483 /* I/O port, IRQ, Buffer address, Env. var, Buf selector. */
- 16484 { 0x280, 3, 0xD0000, "DPETH0", DP_ETH0_SELECTOR },
- .Ep 210 src/kernel/dp8390.c
- 16485 { 0x300, 5, 0xCC000, "DPETH1", DP_ETH1_SELECTOR },
- 16486 };
- 16487
- 16488 /* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
- 16489 * the error: "array size is negative".
- 16490 */
- 16491 extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
- 16492
- 16493
- 16494 _PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
- 16495 int vectored) );
- 16496 _PROTOTYPE( static void do_vread, (message *mp, int vectored) );
- 16497 _PROTOTYPE( static void do_init, (message *mp) );
- 16498 _PROTOTYPE( static void do_int, (dpeth_t *dep) );
- 16499 _PROTOTYPE( static void do_getstat, (message *mp) );
- 16500 _PROTOTYPE( static void do_stop, (message *mp) );
- 16501 _PROTOTYPE( static void dp_init, (dpeth_t *dep) );
- 16502 _PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) );
- 16503 _PROTOTYPE( static void dp_reinit, (dpeth_t *dep) );
- 16504 _PROTOTYPE( static void dp_reset, (dpeth_t *dep) );
- 16505 _PROTOTYPE( static void dp_check_ints, (dpeth_t *dep) );
- 16506 _PROTOTYPE( static void dp_recv, (dpeth_t *dep) );
- 16507 _PROTOTYPE( static void dp_send, (dpeth_t *dep) );
- 16508 _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
- 16509 size_t offset, size_t size, void *dst) );
- 16510 _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
- 16511 size_t offset, size_t size, void *dst) );
- 16512 _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
- 16513 size_t offset, size_t size, void *dst) );
- 16514 _PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
- 16515 int length) );
- 16516 _PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
- 16517 vir_bytes offset, int nic_addr, vir_bytes count) );
- 16518 _PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
- 16519 iovec_dat_t *iovp, vir_bytes offset,
- 16520 int nic_addr, vir_bytes count) );
- 16521 _PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
- 16522 iovec_dat_t *iovp, vir_bytes offset,
- 16523 int nic_addr, vir_bytes count) );
- 16524 _PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
- 16525 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
- 16526 _PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
- 16527 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
- 16528 _PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
- 16529 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
- 16530 _PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
- 16531 _PROTOTYPE( static int dp_handler, (int irq) );
- 16532 _PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
- 16533 _PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
- 16534 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
- 16535 _PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
- 16536 _PROTOTYPE( static void mess_reply, (message *req, message *reply) );
- 16537 _PROTOTYPE( static void get_userdata, (int user_proc,
- 16538 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
- 16539 _PROTOTYPE( static void put_userdata, (int user_proc,
- 16540 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
- 16541
- 16542 /*===========================================================================*
- 16543 * dpeth_task *
- 16544 *===========================================================================*/
- .Op 211 src/kernel/dp8390.c
- 16545 void dp8390_task()
- 16546 {
- 16547 message m;
- 16548 int i, irq, r;
- 16549 dpeth_t *dep;
- 16550 long v;
- 16551
- 16552 dpeth_tasknr= proc_number(proc_ptr);
- 16553
- 16554 v= 0xFFFF;
- 16555 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- 16556 eth_ign_proto= htons((u16_t) v);
- 16557
- 16558 while (TRUE)
- 16559 {
- 16560 if ((r= receive(ANY, &m)) != OK)
- 16561 panic("dp8390: receive failed", r);
- 16562
- 16563 switch (m.m_type)
- 16564 {
- 16565 case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break;
- 16566 case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break;
- 16567 case DL_READ: do_vread(&m, FALSE); break;
- 16568 case DL_READV: do_vread(&m, TRUE); break;
- 16569 case DL_INIT: do_init(&m); break;
- 16570 case DL_GETSTAT: do_getstat(&m); break;
- 16571 case DL_STOP: do_stop(&m); break;
- 16572 case HARD_INT:
- 16573 for (i= 0, dep= &de_table[0]; i<DE_PORT_NR; i++, dep++)
- 16574 {
- 16575 if (dep->de_mode != DEM_ENABLED)
- 16576 continue;
- 16577 assert(dep->de_flags & DEF_ENABLED);
- 16578 irq= dep->de_irq;
- 16579 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
- 16580 if (int_pending[irq])
- 16581 {
- 16582 int_pending[irq]= 0;
- 16583 dp_check_ints(dep);
- 16584 do_int(dep);
- 16585 }
- 16586 }
- 16587 break;
- 16588 default:
- 16589 panic("dp8390: illegal message", m.m_type);
- 16590 }
- 16591 }
- 16592 }
- 16595 /*===========================================================================*
- 16596 * dp_dump *
- 16597 *===========================================================================*/
- 16598 void dp_dump()
- 16599 {
- 16600 dpeth_t *dep;
- 16601 int i, isr;
- 16602
- 16603 printf("n");
- 16604 for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
- .Ep 212 src/kernel/dp8390.c
- 16605 {
- 16606 if (dep->de_mode == DEM_DISABLED)
- 16607 printf("dp8390 port %d is disabledn", i);
- 16608 else if (dep->de_mode == DEM_SINK)
- 16609 printf("dp8390 port %d is in sink moden", i);
- 16610
- 16611 if (dep->de_mode != DEM_ENABLED)
- 16612 continue;
- 16613
- 16614 printf("dp8390 statistics of port %d:n", i);
- 16615
- 16616 printf("recvErr :%8ldt", dep->de_stat.ets_recvErr);
- 16617 printf("sendErr :%8ldt", dep->de_stat.ets_sendErr);
- 16618 printf("OVW :%8ldn", dep->de_stat.ets_OVW);
- 16619
- 16620 printf("CRCerr :%8ldt", dep->de_stat.ets_CRCerr);
- 16621 printf("frameAll :%8ldt", dep->de_stat.ets_frameAll);
- 16622 printf("missedP :%8ldn", dep->de_stat.ets_missedP);
- 16623
- 16624 printf("packetR :%8ldt", dep->de_stat.ets_packetR);
- 16625 printf("packetT :%8ldt", dep->de_stat.ets_packetT);
- 16626 printf("transDef :%8ldn", dep->de_stat.ets_transDef);
- 16627
- 16628 printf("collision :%8ldt", dep->de_stat.ets_collision);
- 16629 printf("transAb :%8ldt", dep->de_stat.ets_transAb);
- 16630 printf("carrSense :%8ldn", dep->de_stat.ets_carrSense);
- 16631
- 16632 printf("fifoUnder :%8ldt", dep->de_stat.ets_fifoUnder);
- 16633 printf("fifoOver :%8ldt", dep->de_stat.ets_fifoOver);
- 16634 printf("CDheartbeat:%8ldn", dep->de_stat.ets_CDheartbeat);
- 16635
- 16636 printf("OWC :%8ldt", dep->de_stat.ets_OWC);
- 16637
- 16638 isr= inb_reg0(dep, DP_ISR);
- 16639 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%xn", isr,
- 16640 inb_reg0(dep, DP_ISR), dep->de_flags);
- 16641 }
- 16642 }
- 16645 /*===========================================================================*
- 16646 * dp8390_stop *
- 16647 *===========================================================================*/
- 16648 void dp8390_stop()
- 16649 {
- 16650 message mess;
- 16651 int i;
- 16652
- 16653 for (i= 0; i<DE_PORT_NR; i++)
- 16654 {
- 16655 if (de_table[i].de_mode != DEM_ENABLED)
- 16656 continue;
- 16657 mess.m_type= DL_STOP;
- 16658 mess.DL_PORT= i;
- 16659 do_stop(&mess);
- 16660 }
- 16661 }
- 16664 /*===========================================================================*
- .Op 213 src/kernel/dp8390.c
- 16665 * do_vwrite *
- 16666 *===========================================================================*/
- 16667 static void do_vwrite(mp, from_int, vectored)
- 16668 message *mp;
- 16669 int from_int;
- 16670 int vectored;
- 16671 {
- 16672 int port, count, size;
- 16673 int sendq_head;
- 16674 dpeth_t *dep;
- 16675
- 16676 port = mp->DL_PORT;
- 16677 count = mp->DL_COUNT;
- 16678 if (port < 0 || port >= DE_PORT_NR)
- 16679 panic("dp8390: illegal port", port);
- 16680 dep= &de_table[port];
- 16681 dep->de_client= mp->DL_PROC;
- 16682
- 16683 if (dep->de_mode == DEM_SINK)
- 16684 {
- 16685 assert(!from_int);
- 16686 dep->de_flags |= DEF_PACK_SEND;
- 16687 reply(dep, OK, FALSE);
- 16688 return;
- 16689 }
- 16690 assert(dep->de_mode == DEM_ENABLED);
- 16691 assert(dep->de_flags & DEF_ENABLED);
- 16692 if (dep->de_flags & DEF_SEND_AVAIL)
- 16693 panic("dp8390: send already in progress", NO_NUM);
- 16694
- 16695 sendq_head= dep->de_sendq_head;
- 16696 if (dep->de_sendq[sendq_head].sq_filled)
- 16697 {
- 16698 if (from_int)
- 16699 panic("dp8390: should not be sendingn", NO_NUM);
- 16700 dep->de_sendmsg= *mp;
- 16701 dep->de_flags |= DEF_SEND_AVAIL;
- 16702 reply(dep, OK, FALSE);
- 16703 return;
- 16704 }
- 16705 assert(!(dep->de_flags & DEF_PACK_SEND));
- 16706
- 16707 if (vectored)
- 16708 {
- 16709 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- 16710 (count > IOVEC_NR ? IOVEC_NR : count) *
- 16711 sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
- 16712 dep->de_write_iovec.iod_iovec_s = count;
- 16713 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
- 16714 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
- 16715
- 16716 dep->de_tmp_iovec = dep->de_write_iovec;
- 16717 size = calc_iovec_size(&dep->de_tmp_iovec);
- 16718 }
- 16719 else
- 16720 {
- 16721 dep->de_write_iovec.iod_iovec[0].iov_addr =
- 16722 (vir_bytes) mp->DL_ADDR;
- 16723 dep->de_write_iovec.iod_iovec[0].iov_size =
- 16724 mp->DL_COUNT;
- .Ep 214 src/kernel/dp8390.c
- 16725 dep->de_write_iovec.iod_iovec_s = 1;
- 16726 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
- 16727 dep->de_write_iovec.iod_iovec_addr = 0;
- 16728 size= mp->DL_COUNT;
- 16729 }
- 16730 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
- 16731 {
- 16732 panic("dp8390: invalid packet size", size);
- 16733 }
- 16734 (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
- 16735 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
- 16736 size);
- 16737 dep->de_sendq[sendq_head].sq_filled= TRUE;
- 16738 if (dep->de_sendq_tail == sendq_head)
- 16739 {
- 16740 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
- 16741 outb_reg0(dep, DP_TBCR1, size >> 8);
- 16742 outb_reg0(dep, DP_TBCR0, size & 0xff);
- 16743 outb_reg0(dep, DP_CR, CR_TXP); /* there it goes.. */
- 16744 }
- 16745 else
- 16746 dep->de_sendq[sendq_head].sq_size= size;
- 16747
- 16748 if (++sendq_head == dep->de_sendq_nr)
- 16749 sendq_head= 0;
- 16750 assert(sendq_head < SENDQ_NR);
- 16751 dep->de_sendq_head= sendq_head;
- 16752
- 16753 dep->de_flags |= DEF_PACK_SEND;
- 16754
- 16755 /* If the interrupt handler called, don't send a reply. The reply
- 16756 * will be sent after all interrupts are handled.
- 16757 */
- 16758 if (from_int)
- 16759 return;
- 16760 reply(dep, OK, FALSE);
- 16761
- 16762 assert(dep->de_mode == DEM_ENABLED);
- 16763 assert(dep->de_flags & DEF_ENABLED);
- 16764 }
- 16767 /*===========================================================================*
- 16768 * do_vread *
- 16769 *===========================================================================*/
- 16770 static void do_vread(mp, vectored)
- 16771 message *mp;
- 16772 int vectored;
- 16773 {
- 16774 int port, count;
- 16775 int size;
- 16776 dpeth_t *dep;
- 16777
- 16778 port = mp->DL_PORT;
- 16779 count = mp->DL_COUNT;
- 16780 if (port < 0 || port >= DE_PORT_NR)
- 16781 panic("dp8390: illegal port", port);
- 16782 dep= &de_table[port];
- 16783 dep->de_client= mp->DL_PROC;
- 16784 if (dep->de_mode == DEM_SINK)
- .Op 215 src/kernel/dp8390.c
- 16785 {
- 16786 reply(dep, OK, FALSE);
- 16787 return;
- 16788 }
- 16789 assert(dep->de_mode == DEM_ENABLED);
- 16790 assert(dep->de_flags & DEF_ENABLED);
- 16791
- 16792 if(dep->de_flags & DEF_READING)
- 16793 panic("dp8390: read already in progress", NO_NUM);
- 16794
- 16795 if (vectored)
- 16796 {
- 16797 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- 16798 (count > IOVEC_NR ? IOVEC_NR : count) *
- 16799 sizeof(iovec_t), dep->de_read_iovec.iod_iovec);
- 16800 dep->de_read_iovec.iod_iovec_s = count;
- 16801 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- 16802 dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
- 16803
- 16804 dep->de_tmp_iovec = dep->de_read_iovec;
- 16805 size= calc_iovec_size(&dep->de_tmp_iovec);
- 16806 }
- 16807 else
- 16808 {
- 16809 dep->de_read_iovec.iod_iovec[0].iov_addr =
- 16810 (vir_bytes) mp->DL_ADDR;
- 16811 dep->de_read_iovec.iod_iovec[0].iov_size =
- 16812 mp->DL_COUNT;
- 16813 dep->de_read_iovec.iod_iovec_s = 1;
- 16814 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- 16815 dep->de_read_iovec.iod_iovec_addr = 0;
- 16816 size= count;
- 16817 }
- 16818 if (size < ETH_MAX_PACK_SIZE)
- 16819 panic("dp8390: wrong packet size", size);
- 16820 dep->de_flags |= DEF_READING;
- 16821
- 16822 dp_recv(dep);
- 16823
- 16824 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
- 16825 (DEF_READING|DEF_STOPPED))
- 16826 {
- 16827 /* The chip is stopped, and all arrived packets are
- 16828 * delivered.
- 16829 */
- 16830 dp_reset(dep);
- 16831 }
- 16832 reply(dep, OK, FALSE);
- 16833 }
- 16836 /*===========================================================================*
- 16837 * do_init *
- 16838 *===========================================================================*/
- 16839 static void do_init(mp)
- 16840 message *mp;
- 16841 {
- 16842 int port;
- 16843 dpeth_t *dep;
- 16844 message reply_mess;
- .Ep 216 src/kernel/dp8390.c
- 16845
- 16846 port = mp->DL_PORT;
- 16847 if (port < 0 || port >= DE_PORT_NR)
- 16848 {
- 16849 reply_mess.m_type= DL_INIT_REPLY;
- 16850 reply_mess.m3_i1= ENXIO;
- 16851 mess_reply(mp, &reply_mess);
- 16852 return;
- 16853 }
- 16854 dep= &de_table[port];
- 16855 if (dep->de_mode == DEM_DISABLED)
- 16856 {
- 16857 /* This is the default, try to (re)locate the device. */
- 16858 conf_hw(dep);
- 16859 if (dep->de_mode == DEM_DISABLED)
- 16860 {
- 16861 /* Probe failed, or the device is configured off. */
- 16862 reply_mess.m_type= DL_INIT_REPLY;
- 16863 reply_mess.m3_i1= ENXIO;
- 16864 mess_reply(mp, &reply_mess);
- 16865 return;
- 16866 }
- 16867 if (dep->de_mode == DEM_ENABLED)
- 16868 dp_init(dep);
- 16869 }
- 16870
- 16871 if (dep->de_mode == DEM_SINK)
- 16872 {
- 16873 dep->de_address.ea_addr[0] =
- 16874 dep->de_address.ea_addr[1] =
- 16875 dep->de_address.ea_addr[2] =
- 16876 dep->de_address.ea_addr[3] =
- 16877 dep->de_address.ea_addr[4] =
- 16878 dep->de_address.ea_addr[5] = 0;
- 16879 dp_confaddr(dep);
- 16880 reply_mess.m_type = DL_INIT_REPLY;
- 16881 reply_mess.m3_i1 = mp->DL_PORT;
- 16882 reply_mess.m3_i2 = DE_PORT_NR;
- 16883 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
- 16884 mess_reply(mp, &reply_mess);
- 16885 return;
- 16886 }
- 16887 assert(dep->de_mode == DEM_ENABLED);
- 16888 assert(dep->de_flags & DEF_ENABLED);
- 16889
- 16890 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
- 16891
- 16892 if (mp->DL_MODE & DL_PROMISC_REQ)
- 16893 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
- 16894 if (mp->DL_MODE & DL_MULTI_REQ)
- 16895 dep->de_flags |= DEF_MULTI;
- 16896 if (mp->DL_MODE & DL_BROAD_REQ)
- 16897 dep->de_flags |= DEF_BROAD;
- 16898
- 16899 dep->de_client = mp->m_source;
- 16900 dp_reinit(dep);
- 16901
- 16902 reply_mess.m_type = DL_INIT_REPLY;
- 16903 reply_mess.m3_i1 = mp->DL_PORT;
- 16904 reply_mess.m3_i2 = DE_PORT_NR;
- .Op 217 src/kernel/dp8390.c
- 16905 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
- 16906
- 16907 mess_reply(mp, &reply_mess);
- 16908 }
- 16910 /*===========================================================================*
- 16911 * do_int *
- 16912 *===========================================================================*/
- 16913 static void do_int(dep)
- 16914 dpeth_t *dep;
- 16915 {
- 16916 if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
- 16917 reply(dep, OK, TRUE);
- 16918 }
- 16921 /*===========================================================================*
- 16922 * do_getstat *
- 16923 *===========================================================================*/
- 16924 static void do_getstat(mp)
- 16925 message *mp;
- 16926 {
- 16927 int port;
- 16928 dpeth_t *dep;
- 16929
- 16930 port = mp->DL_PORT;
- 16931 if (port < 0 || port >= DE_PORT_NR)
- 16932 panic("dp8390: illegal port", port);
- 16933 dep= &de_table[port];
- 16934 dep->de_client= mp->DL_PROC;
- 16935 if (dep->de_mode == DEM_SINK)
- 16936 {
- 16937 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- 16938 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
- 16939 reply(dep, OK, FALSE);
- 16940 return;
- 16941 }
- 16942 assert(dep->de_mode == DEM_ENABLED);
- 16943 assert(dep->de_flags & DEF_ENABLED);
- 16944
- 16945 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
- 16946 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
- 16947 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
- 16948
- 16949 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- 16950 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
- 16951 reply(dep, OK, FALSE);
- 16952 }
- 16955 /*===========================================================================*
- 16956 * do_stop *
- 16957 *===========================================================================*/
- 16958 static void do_stop(mp)
- 16959 message *mp;
- 16960 {
- 16961 int port;
- 16962 dpeth_t *dep;
- 16963
- 16964 port = mp->DL_PORT;
- .Ep 218 src/kernel/dp8390.c
- 16965
- 16966 if (port < 0 || port >= DE_PORT_NR)
- 16967 panic("dp8390: illegal port", port);
- 16968 dep= &de_table[port];
- 16969 if (dep->de_mode == DEM_SINK)
- 16970 return;
- 16971 assert(dep->de_mode == DEM_ENABLED);
- 16972
- 16973 if (!(dep->de_flags & DEF_ENABLED))
- 16974 return;
- 16975
- 16976 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
- 16977 (dep->de_stopf)(dep);
- 16978
- 16979 dep->de_flags= DEF_EMPTY;
- 16980 }
- 16983 /*===========================================================================*
- 16984 * dp_init *
- 16985 *===========================================================================*/
- 16986 static void dp_init(dep)
- 16987 dpeth_t *dep;
- 16988 {
- 16989 int dp_rcr_reg;
- 16990 int i;
- 16991
- 16992 /* General initialization */
- 16993 dep->de_flags = DEF_EMPTY;
- 16994 (*dep->de_initf)(dep);
- 16995
- 16996 dp_confaddr(dep);
- 16997
- 16998 /* Initialization of the dp8390 */
- 16999 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
- 17000 outb_reg0(dep, DP_IMR, 0);
- 17001 outb_reg0(dep, DP_PSTART, dep->de_startpage);
- 17002 outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
- 17003 outb_reg0(dep, DP_BNRY, dep->de_startpage);
- 17004 outb_reg0(dep, DP_RCR, RCR_MON);
- 17005 outb_reg0(dep, DP_TCR, TCR_NORMAL);
- 17006 if (dep->de_16bit)
- 17007 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
- 17008 else
- 17009 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
- 17010 outb_reg0(dep, DP_RBCR0, 0);
- 17011 outb_reg0(dep, DP_RBCR1, 0);
- 17012 outb_reg0(dep, DP_ISR, 0xFF);
- 17013 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT);
- 17014
- 17015 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
- 17016 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
- 17017 outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
- 17018 outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
- 17019 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
- 17020 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
- 17021
- 17022 outb_reg1(dep, DP_MAR0, 0xff);
- 17023 outb_reg1(dep, DP_MAR1, 0xff);
- 17024 outb_reg1(dep, DP_MAR2, 0xff);
- .Op 219 src/kernel/dp8390.c
- 17025 outb_reg1(dep, DP_MAR3, 0xff);
- 17026 outb_reg1(dep, DP_MAR4, 0xff);
- 17027 outb_reg1(dep, DP_MAR5, 0xff);
- 17028 outb_reg1(dep, DP_MAR6, 0xff);
- 17029 outb_reg1(dep, DP_MAR7, 0xff);
- 17030
- 17031 outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
- 17032 outb_reg1(dep, DP_CR, CR_PS_P0 | CR_DM_ABORT);
- 17033
- 17034 dp_rcr_reg = 0;
- 17035 if (dep->de_flags & DEF_PROMISC)
- 17036 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
- 17037 if (dep->de_flags & DEF_BROAD)
- 17038 dp_rcr_reg |= RCR_AB;
- 17039 if (dep->de_flags & DEF_MULTI)
- 17040 dp_rcr_reg |= RCR_AM;
- 17041 outb_reg0(dep, DP_RCR, dp_rcr_reg);
- 17042 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
- 17043 inb_reg0(dep, DP_CNTR1);
- 17044 inb_reg0(dep, DP_CNTR2);
- 17045
- 17046 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
- 17047 IMR_OVWE | IMR_CNTE);
- 17048 outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT);
- 17049
- 17050 /* Finish the initialization. */
- 17051 dep->de_flags |= DEF_ENABLED;
- 17052 for (i= 0; i<dep->de_sendq_nr; i++)
- 17053 dep->de_sendq[i].sq_filled= 0;
- 17054 dep->de_sendq_head= 0;
- 17055 dep->de_sendq_tail= 0;
- 17056 if (!dep->de_prog_IO)
- 17057 {
- 17058 dep->de_user2nicf= dp_user2nic;
- 17059 dep->de_nic2userf= dp_nic2user;
- 17060 dep->de_getblockf= dp_getblock;
- 17061 }
- 17062 else if (dep->de_16bit)
- 17063 {
- 17064 dep->de_user2nicf= dp_pio16_user2nic;
- 17065 dep->de_nic2userf= dp_pio16_nic2user;
- 17066 dep->de_getblockf= dp_pio16_getblock;
- 17067 }
- 17068 else
- 17069 {
- 17070 dep->de_user2nicf= dp_pio8_user2nic;
- 17071 dep->de_nic2userf= dp_pio8_nic2user;
- 17072 dep->de_getblockf= dp_pio8_getblock;
- 17073 }
- 17074
- 17075 /* set the interrupt handler */
- 17076 put_irq_handler(dep->de_irq, dp_handler);
- 17077 enable_irq(dep->de_irq);
- 17078 }
- 17081 /*===========================================================================*
- 17082 * dp_confaddr *
- 17083 *===========================================================================*/
- 17084 static void dp_confaddr(dep)
- .Ep 220 src/kernel/dp8390.c
- 17085 dpeth_t *dep;
- 17086 {
- 17087 int i;
- 17088 char eakey[16];
- 17089 static char eafmt[]= "x:x:x:x:x:x";
- 17090 long v;
- 17091
- 17092 /* User defined ethernet address? */
- 17093 strcpy(eakey, dp_conf[dep-de_table].dpc_envvar);
- 17094 strcat(eakey, "_EA");
- 17095
- 17096 for (i= 0; i < 6; i++)
- 17097 {
- 17098 v= dep->de_address.ea_addr[i];
- 17099 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
- 17100 break;
- 17101 dep->de_address.ea_addr[i]= v;
- 17102 }
- 17103
- 17104 if (i != 0 && i != 6)
- 17105 {
- 17106 /* It's all or nothing; force a panic. */
- 17107 (void) env_parse(eakey, "?", 0, &v, 0L, 0L);
- 17108 }
- 17109 }
- 17112 /*===========================================================================*
- 17113 * dp_reinit *
- 17114 *===========================================================================*/
- 17115 static void dp_reinit(dep)
- 17116 dpeth_t *dep;
- 17117 {
- 17118 int dp_rcr_reg;
- 17119
- 17120 outb_reg0(dep, DP_CR, CR_PS_P0);
- 17121
- 17122 dp_rcr_reg = 0;
- 17123 if (dep->de_flags & DEF_PROMISC)
- 17124 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
- 17125 if (dep->de_flags & DEF_BROAD)
- 17126 dp_rcr_reg |= RCR_AB;
- 17127 if (dep->de_flags & DEF_MULTI)
- 17128 dp_rcr_reg |= RCR_AM;
- 17129 outb_reg0(dep, DP_RCR, dp_rcr_reg);
- 17130 }
- 17133 /*===========================================================================*
- 17134 * dp_reset *
- 17135 *===========================================================================*/
- 17136 static void dp_reset(dep)
- 17137 dpeth_t *dep;
- 17138 {
- 17139 int i;
- 17140
- 17141 /* Stop chip */
- 17142 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
- 17143 outb_reg0(dep, DP_RBCR0, 0);
- 17144 outb_reg0(dep, DP_RBCR1, 0);
- .Op 221 src/kernel/dp8390.c
- 17145 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
- 17146 ; /* Do nothing */
- 17147 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
- 17148 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
- 17149 outb_reg0(dep, DP_TCR, TCR_NORMAL|TCR_OFST);
- 17150
- 17151 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
- 17152 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
- 17153 ; /* Do nothing */
- 17154 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
- 17155
- 17156 /* Reset the transmit ring. If we were transmitting a packet, we
- 17157 * pretend that the packet is processed. Higher layers will
- 17158 * retransmit if the packet wasn't actually sent.
- 17159 */
- 17160 dep->de_sendq_head= dep->de_sendq_tail= 0;
- 17161 for (i= 0; i<dep->de_sendq_nr; i++)
- 17162 dep->de_sendq[i].sq_filled= 0;
- 17163 dp_send(dep);
- 17164 dep->de_flags &= ~DEF_STOPPED;
- 17165 }
- 17168 /*===========================================================================*
- 17169 * dp_check_ints *
- 17170 *===========================================================================*/
- 17171 static void dp_check_ints(dep)
- 17172 dpeth_t *dep;
- 17173 {
- 17174 int isr, tsr;
- 17175 int size, sendq_tail;
- 17176
- 17177 if (!(dep->de_flags & DEF_ENABLED))
- 17178 panic("dp8390: got premature interrupt", NO_NUM);
- 17179
- 17180 for(;;)
- 17181 {
- 17182 isr = inb_reg0(dep, DP_ISR);
- 17183 if (!isr)
- 17184 break;
- 17185 outb_reg0(dep, DP_ISR, isr);
- 17186 if (isr & (ISR_PTX|ISR_TXE))
- 17187 {
- 17188 if (isr & ISR_TXE)
- 17189 {
- 17190 #if DEBUG
- 17191 { printf("dp8390: got send Errorn"); }
- 17192 #endif
- 17193 dep->de_stat.ets_sendErr++;
- 17194 }
- 17195 else
- 17196 {
- 17197 tsr = inb_reg0(dep, DP_TSR);
- 17198
- 17199 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
- 17200 if (tsr & TSR_DFR) dep->de_stat.ets_transDef++;
- 17201 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
- 17202 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
- 17203 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
- 17204 if (tsr & TSR_FU
- .Ep 222 src/kernel/dp8390.c
- 17205 && ++dep->de_stat.ets_fifoUnder <= 10)
- 17206 {
- 17207 printf("dp8390: fifo underrunn");
- 17208 }
- 17209 if (tsr & TSR_CDH
- 17210 && ++dep->de_stat.ets_CDheartbeat <= 10)
- 17211 {
- 17212 printf(
- 17213 "dp8390: CD heart beat failuren");
- 17214 }
- 17215 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
- 17216 }
- 17217 sendq_tail= dep->de_sendq_tail;
- 17218
- 17219 if (!(dep->de_sendq[sendq_tail].sq_filled))
- 17220 {
- 17221 /* Software bug? */
- 17222 assert(!debug);
- 17223
- 17224 /* Or hardware bug? */
- 17225 printf(
- 17226 "dp8390: transmit interrupt, but not sendingn");
- 17227 continue;
- 17228 }
- 17229 dep->de_sendq[sendq_tail].sq_filled= 0;
- 17230 if (++sendq_tail == dep->de_sendq_nr)
- 17231 sendq_tail= 0;
- 17232 dep->de_sendq_tail= sendq_tail;
- 17233 if (dep->de_sendq[sendq_tail].sq_filled)
- 17234 {
- 17235 size= dep->de_sendq[sendq_tail].sq_size;
- 17236 outb_reg0(dep, DP_TPSR,
- 17237 dep->de_sendq[sendq_tail].sq_sendpage);
- 17238 outb_reg0(dep, DP_TBCR1, size >> 8);
- 17239 outb_reg0(dep, DP_TBCR0, size & 0xff);
- 17240 outb_reg0(dep, DP_CR, CR_TXP); /* there is goes.. */
- 17241 }
- 17242 if (dep->de_flags & DEF_SEND_AVAIL)
- 17243 dp_send(dep);
- 17244 }
- 17245
- 17246 if (isr & ISR_PRX)
- 17247 dp_recv(dep);
- 17248
- 17249 if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
- 17250 if (isr & ISR_CNT)
- 17251 {
- 17252 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
- 17253 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
- 17254 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
- 17255 }
- 17256 if (isr & ISR_OVW)
- 17257 {
- 17258 #if DEBUG
- 17259 { printW(); printf("dp8390: got overwrite warningn"); }
- 17260 #endif
- 17261 }
- 17262 if (isr & ISR_RDC)
- 17263 {
- 17264 /* Nothing to do */
- .Op 223 src/kernel/dp8390.c
- 17265 }
- 17266 if (isr & ISR_RST)
- 17267 {
- 17268 /* this means we got an interrupt but the ethernet
- 17269 * chip is shutdown. We set the flag DEF_STOPPED,
- 17270 * and continue processing arrived packets. When the
- 17271 * receive buffer is empty, we reset the dp8390.
- 17272 */
- 17273 #if DEBUG
- 17274 { printW(); printf("dp8390: NIC stoppedn"); }
- 17275 #endif
- 17276 dep->de_flags |= DEF_STOPPED;
- 17277 break;
- 17278 }
- 17279 }
- 17280 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
- 17281 (DEF_READING|DEF_STOPPED))
- 17282 {
- 17283 /* The chip is stopped, and all arrived packets are
- 17284 * delivered.
- 17285 */
- 17286 dp_reset(dep);
- 17287 }
- 17288 }
- 17291 /*===========================================================================*
- 17292 * dp_recv *
- 17293 *===========================================================================*/
- 17294 static void dp_recv(dep)
- 17295 dpeth_t *dep;
- 17296 {
- 17297 dp_rcvhdr_t header;
- 17298 unsigned pageno, curr, next;
- 17299 vir_bytes length;
- 17300 int packet_processed, r;
- 17301 u16_t eth_type;
- 17302
- 17303 packet_processed = FALSE;
- 17304 pageno = inb_reg0(dep, DP_BNRY) + 1;
- 17305 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
- 17306
- 17307 do
- 17308 {
- 17309 outb_reg0(dep, DP_CR, CR_PS_P1);
- 17310 curr = inb_reg1(dep, DP_CURR);
- 17311 outb_reg0(dep, DP_CR, CR_PS_P0);
- 17312
- 17313 if (curr == pageno) break;
- 17314
- 17315 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
- 17316 &header);
- 17317 (dep->de_getblockf)(dep, pageno, sizeof(header) +
- 17318 2*sizeof(ether_addr_t), sizeof(eth_type), ð_type);
- 17319
- 17320 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
- 17321 sizeof(dp_rcvhdr_t);
- 17322 next = header.dr_next;
- 17323 if (length < 60 || length > 1514)
- 17324 {
- .Ep 224 src/kernel/dp8390.c
- 17325 printf(
- 17326 "dp8390: packet with strange length arrived: %dn",
- 17327 length);
- 17328 next= curr;
- 17329 }
- 17330 else if (next < dep->de_startpage || next >= dep->de_stoppage)
- 17331 {
- 17332 printf("dp8390: strange next pagen");
- 17333 next= curr;
- 17334 }
- 17335 else if (eth_type == eth_ign_proto)
- 17336 {
- 17337 /* hack: ignore packets of a given protocol, useful
- 17338 * if you share a net with 80 computers sending
- 17339 * Amoeba FLIP broadcasts. (Protocol 0x8146.)
- 17340 */
- 17341 static int first= 1;
- 17342 if (first)
- 17343 {
- 17344 first= 0;
- 17345 printW();
- 17346 printf("dropping proto %04x packetn",
- 17347 ntohs(eth_ign_proto));
- 17348 }
- 17349 dep->de_stat.ets_packetR++;
- 17350 next = curr;
- 17351 }
- 17352 else if (header.dr_status & RSR_FO)
- 17353 {
- 17354 /* This is very serious, so we issue a warning and
- 17355 * reset the buffers */
- 17356 printf(
- 17357 "dp8390: fifo overrun, resetting receive buffern");
- 17358 dep->de_stat.ets_fifoOver++;
- 17359 next = curr;
- 17360 }
- 17361 else if ((header.dr_status & RSR_PRX) &&
- 17362 (dep->de_flags & DEF_ENABLED))
- 17363 {
- 17364 r = dp_pkt2user(dep, pageno, length);
- 17365 if (r != OK)
- 17366 return;
- 17367
- 17368 packet_processed = TRUE;
- 17369 dep->de_stat.ets_packetR++;
- 17370 }
- 17371 if (next == dep->de_startpage)
- 17372 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
- 17373 else
- 17374 outb_reg0(dep, DP_BNRY, next - 1);
- 17375
- 17376 pageno = next;
- 17377 }
- 17378 while (!packet_processed);
- 17379 }
- 17382 /*===========================================================================*
- 17383 * dp_send *
- 17384 *===========================================================================*/
- .Op 225 src/kernel/dp8390.c
- 17385 static void dp_send(dep)
- 17386 dpeth_t *dep;
- 17387 {
- 17388 if (!(dep->de_flags & DEF_SEND_AVAIL))
- 17389 return;
- 17390
- 17391 dep->de_flags &= ~DEF_SEND_AVAIL;
- 17392 switch(dep->de_sendmsg.m_type)
- 17393 {
- 17394 case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
- 17395 case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
- 17396 default:
- 17397 panic("dp8390: wrong type:", dep->de_sendmsg.m_type);
- 17398 break;
- 17399 }
- 17400 }
- 17403 /*===========================================================================*
- 17404 * dp_getblock *
- 17405 *===========================================================================*/
- 17406 static void dp_getblock(dep, page, offset, size, dst)
- 17407 dpeth_t *dep;
- 17408 int page;
- 17409 size_t offset;
- 17410 size_t size;
- 17411 void *dst;
- 17412 {
- 17413 u16_t *ha;
- 17414 int i;
- 17415
- 17416 ha = (u16_t *) dst;
- 17417 offset = page * DP_PAGESIZE + offset;
- 17418 assert(!(size & 1));
- 17419 for (i= 0; i<size; i+=2)
- 17420 {
- 17421 *ha = mem_rdw(dep->de_memsegm, offset+i);
- 17422 ha++;
- 17423 }
- 17424 }
- 17427 /*===========================================================================*
- 17428 * dp_pio8_getblock *
- 17429 *===========================================================================*/
- 17430 static void dp_pio8_getblock(dep, page, offset, size, dst)
- 17431 dpeth_t *dep;
- 17432 int page;
- 17433 size_t offset;
- 17434 size_t size;
- 17435 void *dst;
- 17436 {
- 17437 u8_t *ha;
- 17438 int i;
- 17439
- 17440 ha = (u8_t *) dst;
- 17441 offset = page * DP_PAGESIZE + offset;
- 17442 outb_reg0(dep, DP_RBCR0, size & 0xFF);
- 17443 outb_reg0(dep, DP_RBCR1, size >> 8);
- 17444 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
- .Ep 226 src/kernel/dp8390.c
- 17445 outb_reg0(dep, DP_RSAR1, offset >> 8);
- 17446 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
- 17447
- 17448 for (i= 0; i<size; i++)
- 17449 ha[i]= in_byte(dep->de_data_port);
- 17450 }
- 17453 /*===========================================================================*
- 17454 * dp_pio16_getblock *
- 17455 *===========================================================================*/
- 17456 static void dp_pio16_getblock(dep, page, offset, size, dst)
- 17457 dpeth_t *dep;
- 17458 int page;
- 17459 size_t offset;
- 17460 size_t size;
- 17461 void *dst;
- 17462 {
- 17463 u16_t *ha;
- 17464 int i;
- 17465
- 17466 ha = (u16_t *) dst;
- 17467 offset = page * DP_PAGESIZE + offset;
- 17468 outb_reg0(dep, DP_RBCR0, size & 0xFF);
- 17469 outb_reg0(dep, DP_RBCR1, size >> 8);
- 17470 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
- 17471 outb_reg0(dep, DP_RSAR1, offset >> 8);
- 17472 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
- 17473
- 17474 assert (!(size & 1));
- 17475 size /= 2;
- 17476 for (i= 0; i<size; i++)
- 17477 ha[i]= in_word(dep->de_data_port);
- 17478 }
- 17481 /*===========================================================================*
- 17482 * dp_pkt2user *
- 17483 *===========================================================================*/
- 17484 static int dp_pkt2user(dep, page, length)
- 17485 dpeth_t *dep;
- 17486 int page, length;
- 17487 {
- 17488 int last, count;
- 17489
- 17490 if (!(dep->de_flags & DEF_READING))
- 17491 return EGENERIC;
- 17492
- 17493 last = page + (length - 1) / DP_PAGESIZE;
- 17494 if (last >= dep->de_stoppage)
- 17495 {
- 17496 count = (dep->de_stoppage - page) * DP_PAGESIZE -
- 17497 sizeof(dp_rcvhdr_t);
- 17498
- 17499 /* Save read_iovec since we need it twice. */
- 17500 dep->de_tmp_iovec = dep->de_read_iovec;
- 17501 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
- 17502 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
- 17503 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
- 17504 &dep->de_read_iovec, count, length - count);
- .Op 227 src/kernel/dp8390.c
- 17505 }
- 17506 else
- 17507 {
- 17508 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
- 17509 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
- 17510 }
- 17511
- 17512 dep->de_read_s = length;
- 17513 dep->de_flags |= DEF_PACK_RECV;
- 17514 dep->de_flags &= ~DEF_READING;
- 17515
- 17516 return OK;
- 17517 }
- 17520 /*===========================================================================*
- 17521 * dp_user2nic *
- 17522 *===========================================================================*/
- 17523 static void dp_user2nic(dep, iovp, offset, nic_addr, count)
- 17524 dpeth_t *dep;
- 17525 iovec_dat_t *iovp;
- 17526 vir_bytes offset;
- 17527 int nic_addr;
- 17528 vir_bytes count;
- 17529 {
- 17530 phys_bytes phys_hw, phys_user;
- 17531 int bytes, i;
- 17532
- 17533 phys_hw = dep->de_linmem + nic_addr;
- 17534
- 17535 i= 0;
- 17536 while (count > 0)
- 17537 {
- 17538 if (i >= IOVEC_NR)
- 17539 {
- 17540 dp_next_iovec(iovp);
- 17541 i= 0;
- 17542 continue;
- 17543 }
- 17544 assert(i < iovp->iod_iovec_s);
- 17545 if (offset >= iovp->iod_iovec[i].iov_size)
- 17546 {
- 17547 offset -= iovp->iod_iovec[i].iov_size;
- 17548 i++;
- 17549 continue;
- 17550 }
- 17551 bytes = iovp->iod_iovec[i].iov_size - offset;
- 17552 if (bytes > count)
- 17553 bytes = count;
- 17554
- 17555 phys_user = numap(iovp->iod_proc_nr,
- 17556 iovp->iod_iovec[i].iov_addr + offset, bytes);
- 17557 if (!phys_user)
- 17558 panic("dp8390: umap failedn", NO_NUM);
- 17559 phys_copy(phys_user, phys_hw, (phys_bytes) bytes);
- 17560 count -= bytes;
- 17561 phys_hw += bytes;
- 17562 offset += bytes;
- 17563 }
- 17564 assert(count == 0);
- .Ep 228 src/kernel/dp8390.c
- 17565 }
- 17568 /*===========================================================================*
- 17569 * dp_pio8_user2nic *
- 17570 *===========================================================================*/
- 17571 static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
- 17572 dpeth_t *dep;
- 17573 iovec_dat_t *iovp;
- 17574 vir_bytes offset;
- 17575 int nic_addr;
- 17576 vir_bytes count;
- 17577 {
- 17578 phys_bytes phys_user;
- 17579 int bytes, i;
- 17580
- 17581 outb_reg0(dep, DP_ISR, ISR_RDC);
- 17582
- 17583 outb_reg0(dep, DP_RBCR0, count & 0xFF);
- 17584 outb_reg0(dep, DP_RBCR1, count >> 8);
- 17585 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- 17586 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- 17587 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
- 17588
- 17589 i= 0;
- 17590 while (count > 0)
- 17591 {
- 17592 if (i >= IOVEC_NR)
- 17593 {
- 17594 dp_next_iovec(iovp);
- 17595 i= 0;
- 17596 continue;
- 17597 }
- 17598 assert(i < iovp->iod_iovec_s);
- 17599 if (offset >= iovp->iod_iovec[i].iov_size)
- 17600 {
- 17601 offset -= iovp->iod_iovec[i].iov_size;
- 17602 i++;
- 17603 continue;
- 17604 }
- 17605 bytes = iovp->iod_iovec[i].iov_size - offset;
- 17606 if (bytes > count)
- 17607 bytes = count;
- 17608
- 17609 phys_user = numap(iovp->iod_proc_nr,
- 17610 iovp->iod_iovec[i].iov_addr + offset, bytes);
- 17611 if (!phys_user)
- 17612 panic("dp8390: umap failedn", NO_NUM);
- 17613 port_write_byte(dep->de_data_port, phys_user, bytes);
- 17614 count -= bytes;
- 17615 offset += bytes;
- 17616 }
- 17617 assert(count == 0);
- 17618
- 17619 for (i= 0; i<100; i++)
- 17620 {
- 17621 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
- 17622 break;
- 17623 }
- 17624 if (i == 100)
- .Op 229 src/kernel/dp8390.c
- 17625 {
- 17626 panic("dp8390: remote dma failed to complete", NO_NUM);
- 17627 }
- 17628 }
- 17631 /*===========================================================================*
- 17632 * dp_pio16_user2nic *
- 17633 *===========================================================================*/
- 17634 static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
- 17635 dpeth_t *dep;
- 17636 iovec_dat_t *iovp;
- 17637 vir_bytes offset;
- 17638 int nic_addr;
- 17639 vir_bytes count;
- 17640 {
- 17641 phys_bytes phys_user;
- 17642 vir_bytes ecount;
- 17643 int bytes, i;
- 17644 u8_t two_bytes[2];
- 17645 phys_bytes phys_2bytes;
- 17646 int odd_byte;
- 17647
- 17648 ecount= (count+1) & ~1;
- 17649 phys_2bytes = vir2phys(two_bytes);
- 17650 odd_byte= 0;
- 17651
- 17652 outb_reg0(dep, DP_ISR, ISR_RDC);
- 17653 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
- 17654 outb_reg0(dep, DP_RBCR1, ecount >> 8);
- 17655 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- 17656 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- 17657 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
- 17658
- 17659 i= 0;
- 17660 while (count > 0)
- 17661 {
- 17662 if (i >= IOVEC_NR)
- 17663 {
- 17664 dp_next_iovec(iovp);
- 17665 i= 0;
- 17666 continue;
- 17667 }
- 17668 assert(i < iovp->iod_iovec_s);
- 17669 if (offset >= iovp->iod_iovec[i].iov_size)
- 17670 {
- 17671 offset -= iovp->iod_iovec[i].iov_size;
- 17672 i++;
- 17673 continue;
- 17674 }
- 17675 bytes = iovp->iod_iovec[i].iov_size - offset;
- 17676 if (bytes > count)
- 17677 bytes = count;
- 17678
- 17679 phys_user = numap(iovp->iod_proc_nr,
- 17680 iovp->iod_iovec[i].iov_addr + offset, bytes);
- 17681 if (!phys_user)
- 17682 panic("dp8390: umap failedn", NO_NUM);
- 17683 if (odd_byte)
- 17684 {
- .Ep 230 src/kernel/dp8390.c
- 17685 phys_copy(phys_user, phys_2bytes+1,
- 17686 (phys_bytes) 1);
- 17687 out_word(dep->de_data_port, *(u16_t *)two_bytes);
- 17688 count--;
- 17689 offset++;
- 17690 bytes--;
- 17691 phys_user++;
- 17692 odd_byte= 0;
- 17693 if (!bytes)
- 17694 continue;
- 17695 }
- 17696 ecount= bytes & ~1;
- 17697 if (ecount != 0)
- 17698 {
- 17699 port_write(dep->de_data_port, phys_user, ecount);
- 17700 count -= ecount;
- 17701 offset += ecount;
- 17702 bytes -= ecount;
- 17703 phys_user += ecount;
- 17704 }
- 17705 if (bytes)
- 17706 {
- 17707 assert(bytes == 1);
- 17708 phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);
- 17709 count--;
- 17710 offset++;
- 17711 bytes--;
- 17712 phys_user++;
- 17713 odd_byte= 1;
- 17714 }
- 17715 }
- 17716 assert(count == 0);
- 17717
- 17718 if (odd_byte)
- 17719 out_word(dep->de_data_port, *(u16_t *)two_bytes);
- 17720
- 17721 for (i= 0; i<100; i++)
- 17722 {
- 17723 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
- 17724 break;
- 17725 }
- 17726 if (i == 100)
- 17727 {
- 17728 panic("dp8390: remote dma failed to complete", NO_NUM);
- 17729 }
- 17730 }
- 17733 /*===========================================================================*
- 17734 * dp_nic2user *
- 17735 *===========================================================================*/
- 17736 static void dp_nic2user(dep, nic_addr, iovp, offset, count)
- 17737 dpeth_t *dep;
- 17738 int nic_addr;
- 17739 iovec_dat_t *iovp;
- 17740 vir_bytes offset;
- 17741 vir_bytes count;
- 17742 {
- 17743 phys_bytes phys_hw, phys_user;
- 17744 int bytes, i;
- .Op 231 src/kernel/dp8390.c
- 17745
- 17746 phys_hw = dep->de_linmem + nic_addr;
- 17747
- 17748 i= 0;
- 17749 while (count > 0)
- 17750 {
- 17751 if (i >= IOVEC_NR)
- 17752 {
- 17753 dp_next_iovec(iovp);
- 17754 i= 0;
- 17755 continue;
- 17756 }
- 17757 assert(i < iovp->iod_iovec_s);
- 17758 if (offset >= iovp->iod_iovec[i].iov_size)
- 17759 {
- 17760 offset -= iovp->iod_iovec[i].iov_size;
- 17761 i++;
- 17762 continue;
- 17763 }
- 17764 bytes = iovp->iod_iovec[i].iov_size - offset;
- 17765 if (bytes > count)
- 17766 bytes = count;
- 17767
- 17768 phys_user = numap(iovp->iod_proc_nr,
- 17769 iovp->iod_iovec[i].iov_addr + offset, bytes);
- 17770 if (!phys_user)
- 17771 panic("dp8390: umap failedn", NO_NUM);
- 17772 phys_copy(phys_hw, phys_user, (phys_bytes) bytes);
- 17773 count -= bytes;
- 17774 phys_hw += bytes;
- 17775 offset += bytes;
- 17776 }
- 17777 assert(count == 0);
- 17778 }
- 17781 /*===========================================================================*
- 17782 * dp_pio8_nic2user *
- 17783 *===========================================================================*/
- 17784 static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
- 17785 dpeth_t *dep;
- 17786 int nic_addr;
- 17787 iovec_dat_t *iovp;
- 17788 vir_bytes offset;
- 17789 vir_bytes count;
- 17790 {
- 17791 phys_bytes phys_user;
- 17792 int bytes, i;
- 17793
- 17794 outb_reg0(dep, DP_RBCR0, count & 0xFF);
- 17795 outb_reg0(dep, DP_RBCR1, count >> 8);
- 17796 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- 17797 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- 17798 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
- 17799
- 17800 i= 0;
- 17801 while (count > 0)
- 17802 {
- 17803 if (i >= IOVEC_NR)
- 17804 {
- .Ep 232 src/kernel/dp8390.c
- 17805 dp_next_iovec(iovp);
- 17806 i= 0;
- 17807 continue;
- 17808 }
- 17809 assert(i < iovp->iod_iovec_s);
- 17810 if (offset >= iovp->iod_iovec[i].iov_size)
- 17811 {
- 17812 offset -= iovp->iod_iovec[i].iov_size;
- 17813 i++;
- 17814 continue;
- 17815 }
- 17816 bytes = iovp->iod_iovec[i].iov_size - offset;
- 17817 if (bytes > count)
- 17818 bytes = count;
- 17819
- 17820 phys_user = numap(iovp->iod_proc_nr,
- 17821 iovp->iod_iovec[i].iov_addr + offset, bytes);
- 17822 if (!phys_user)
- 17823 panic("dp8390: umap failedn", NO_NUM);
- 17824 port_read_byte(dep->de_data_port, phys_user, bytes);
- 17825 count -= bytes;
- 17826 offset += bytes;
- 17827 }
- 17828 assert(count == 0);
- 17829 }
- 17832 /*===========================================================================*
- 17833 * dp_pio16_nic2user *
- 17834 *===========================================================================*/
- 17835 static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
- 17836 dpeth_t *dep;
- 17837 int nic_addr;
- 17838 iovec_dat_t *iovp;
- 17839 vir_bytes offset;
- 17840 vir_bytes count;
- 17841 {
- 17842 phys_bytes phys_user;
- 17843 vir_bytes ecount;
- 17844 int bytes, i;
- 17845 u8_t two_bytes[2];
- 17846 phys_bytes phys_2bytes;
- 17847 int odd_byte;
- 17848
- 17849 ecount= (count+1) & ~1;
- 17850 phys_2bytes = vir2phys(two_bytes);
- 17851 odd_byte= 0;
- 17852
- 17853 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
- 17854 outb_reg0(dep, DP_RBCR1, ecount >> 8);
- 17855 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
- 17856 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
- 17857 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
- 17858
- 17859 i= 0;
- 17860 while (count > 0)
- 17861 {
- 17862 if (i >= IOVEC_NR)
- 17863 {
- 17864 dp_next_iovec(iovp);
- .Op 233 src/kernel/dp8390.c
- 17865 i= 0;
- 17866 continue;
- 17867 }
- 17868 assert(i < iovp->iod_iovec_s);
- 17869 if (offset >= iovp->iod_iovec[i].iov_size)
- 17870 {
- 17871 offset -= iovp->iod_iovec[i].iov_size;
- 17872 i++;
- 17873 continue;
- 17874 }
- 17875 bytes = iovp->iod_iovec[i].iov_size - offset;
- 17876 if (bytes > count)
- 17877 bytes = count;
- 17878
- 17879 phys_user = numap(iovp->iod_proc_nr,
- 17880 iovp->iod_iovec[i].iov_addr + offset, bytes);
- 17881 if (!phys_user)
- 17882 panic("dp8390: umap failedn", NO_NUM);
- 17883 if (odd_byte)
- 17884 {
- 17885 phys_copy(phys_2bytes+1, phys_user, (phys_bytes) 1);
- 17886 count--;
- 17887 offset++;
- 17888 bytes--;
- 17889 phys_user++;
- 17890 odd_byte= 0;
- 17891 if (!bytes)
- 17892 continue;
- 17893 }
- 17894 ecount= bytes & ~1;
- 17895 if (ecount != 0)
- 17896 {
- 17897 port_read(dep->de_data_port, phys_user, ecount);
- 17898 count -= ecount;
- 17899 offset += ecount;
- 17900 bytes -= ecount;
- 17901 phys_user += ecount;
- 17902 }
- 17903 if (bytes)
- 17904 {
- 17905 assert(bytes == 1);
- 17906 *(u16_t *)two_bytes= in_word(dep->de_data_port);
- 17907 phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);
- 17908 count--;
- 17909 offset++;
- 17910 bytes--;
- 17911 phys_user++;
- 17912 odd_byte= 1;
- 17913 }
- 17914 }
- 17915 assert(count == 0);
- 17916 }
- 17919 /*===========================================================================*
- 17920 * dp_next_iovec *
- 17921 *===========================================================================*/
- 17922 static void dp_next_iovec(iovp)
- 17923 iovec_dat_t *iovp;
- 17924 {
- .Ep 234 src/kernel/dp8390.c
- 17925 assert(iovp->iod_iovec_s > IOVEC_NR);
- 17926
- 17927 iovp->iod_iovec_s -= IOVEC_NR;
- 17928
- 17929 iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
- 17930
- 17931 get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
- 17932 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
- 17933 sizeof(iovec_t), iovp->iod_iovec);
- 17934 }
- 17937 /*===========================================================================*
- 17938 * dp_handler *
- 17939 *===========================================================================*/
- 17940 static int dp_handler(irq)
- 17941 int irq;
- 17942 {
- 17943 /* DP8390 interrupt, send message and reenable interrupts. */
- 17944
- 17945 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
- 17946 int_pending[irq]= 1;
- 17947 interrupt(dpeth_tasknr);
- 17948 return 1;
- 17949 }
- 17951 /*===========================================================================*
- 17952 * conf_hw *
- 17953 *===========================================================================*/
- 17954 static void conf_hw(dep)
- 17955 dpeth_t *dep;
- 17956 {
- 17957 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
- 17958
- 17959 int ifnr;
- 17960 dp_conf_t *dcp;
- 17961
- 17962 dep->de_mode= DEM_DISABLED; /* Superfluous */
- 17963 ifnr= dep-de_table;
- 17964
- 17965 dcp= &dp_conf[ifnr];
- 17966 update_conf(dep, dcp);
- 17967 if (dep->de_mode != DEM_ENABLED)
- 17968 return;
- 17969 if (!wdeth_probe(dep) && !ne_probe(dep))
- 17970 {
- 17971 printf("dp8390: warning no ethernet card found at 0x%xn",
- 17972 dep->de_base_port);
- 17973 dep->de_mode= DEM_DISABLED;
- 17974 return;
- 17975 }
- 17976
- 17977 /* Allocate a memory segment, programmed I/O should set the
- 17978 * memory segment (linmem) to zero.
- 17979 */
- 17980 if (dep->de_linmem != 0)
- 17981 {
- 17982 if (protected_mode)
- 17983 {
- 17984 init_dataseg(&gdt[dcp->dpc_prot_sel / DESC_SIZE],
- .Op 235 src/kernel/dp8390.c
- 17985 dep->de_linmem, dep->de_ramsize,
- 17986 TASK_PRIVILEGE);
- 17987 dep->de_memsegm= dcp->dpc_prot_sel;
- 17988 }
- 17989 else
- 17990 {
- 17991 dep->de_memsegm= physb_to_hclick(dep->de_linmem);
- 17992 }
- 17993 }
- 17994
- 17995 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
- 17996
- 17997 dep->de_flags = DEF_EMPTY;
- 17998 dep->de_stat = empty_stat;
- 17999 }
- 18002 /*===========================================================================*
- 18003 * update_conf *
- 18004 *===========================================================================*/
- 18005 static void update_conf(dep, dcp)
- 18006 dpeth_t *dep;
- 18007 dp_conf_t *dcp;
- 18008 {
- 18009 long v;
- 18010 static char dpc_fmt[] = "x:d:x";
- 18011
- 18012 /* Get the default settings and modify them from the environment. */
- 18013 dep->de_mode= DEM_SINK;
- 18014 v= dcp->dpc_port;
- 18015 switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &v, 0x000L, 0x3FFL)) {
- 18016 case EP_OFF:
- 18017 dep->de_mode= DEM_DISABLED;
- 18018 break;
- 18019 case EP_ON:
- 18020 case EP_SET:
- 18021 dep->de_mode= DEM_ENABLED; /* Might become disabled if
- 18022 * all probes fail */
- 18023 break;
- 18024 }
- 18025 dep->de_base_port= v;
- 18026
- 18027 v= dcp->dpc_irq | DEI_DEFAULT;
- 18028 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 1, &v, 0L,
- 18029 (long) NR_IRQ_VECTORS - 1);
- 18030 dep->de_irq= v;
- 18031
- 18032 v= dcp->dpc_mem;
- 18033 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 2, &v, 0L, LONG_MAX);
- 18034 dep->de_linmem= v;
- 18035 }
- 18038 /*===========================================================================*
- 18039 * calc_iovec_size *
- 18040 *===========================================================================*/
- 18041 static int calc_iovec_size(iovp)
- 18042 iovec_dat_t *iovp;
- 18043 {
- 18044 /* Calculate the size of a request. Note that the iovec_dat
- .Ep 236 src/kernel/dp8390.c
- 18045 * structure will be unusable after calc_iovec_size.
- 18046 */
- 18047 int size;
- 18048 int i;
- 18049
- 18050 size= 0;
- 18051 i= 0;
- 18052 while (i < iovp->iod_iovec_s)
- 18053 {
- 18054 if (i >= IOVEC_NR)
- 18055 {
- 18056 dp_next_iovec(iovp);
- 18057 i= 0;
- 18058 continue;
- 18059 }
- 18060 size += iovp->iod_iovec[i].iov_size;
- 18061 i++;
- 18062 }
- 18063 return size;
- 18064 }
- 18067 /*===========================================================================*
- 18068 * reply *
- 18069 *===========================================================================*/
- 18070 static void reply(dep, err, may_block)
- 18071 dpeth_t *dep;
- 18072 int err;
- 18073 int may_block;
- 18074 {
- 18075 message reply;
- 18076 int status;
- 18077 int r;
- 18078
- 18079 status = 0;
- 18080 if (dep->de_flags & DEF_PACK_SEND)
- 18081 status |= DL_PACK_SEND;
- 18082 if (dep->de_flags & DEF_PACK_RECV)
- 18083 status |= DL_PACK_RECV;
- 18084
- 18085 reply.m_type = DL_TASK_REPLY;
- 18086 reply.DL_PORT = dep - de_table;
- 18087 reply.DL_PROC = dep->de_client;
- 18088 reply.DL_STAT = status | ((u32_t) err << 16);
- 18089 reply.DL_COUNT = dep->de_read_s;
- 18090 reply.DL_CLCK = get_uptime();
- 18091 r= send(dep->de_client, &reply);
- 18092 #if 0
- 18093 /* XXX What is the reason that this doesn't happen? */
- 18094 if (result == ELOCKED && may_block)
- 18095 return;
- 18096 #endif
- 18097 if (r < 0)
- 18098 panic("dp8390: send failed:", r);
- 18099
- 18100 dep->de_read_s = 0;
- 18101 dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
- 18102 }
- .Op 237 src/kernel/dp8390.c
- 18105 /*===========================================================================*
- 18106 * mess_reply *
- 18107 *===========================================================================*/
- 18108 static void mess_reply(req, reply_mess)
- 18109 message *req;
- 18110 message *reply_mess;
- 18111 {
- 18112 if (send(req->m_source, reply_mess) != OK)
- 18113 panic("dp8390: unable to mess_reply", NO_NUM);
- 18114 }
- 18117 /*===========================================================================*
- 18118 * get_userdata *
- 18119 *===========================================================================*/
- 18120 static void get_userdata(user_proc, user_addr, count, loc_addr)
- 18121 int user_proc;
- 18122 vir_bytes user_addr;
- 18123 vir_bytes count;
- 18124 void *loc_addr;
- 18125 {
- 18126 phys_bytes src;
- 18127
- 18128 src = numap(user_proc, user_addr, count);
- 18129 if (!src)
- 18130 panic("dp8390: umap failed", NO_NUM);
- 18131
- 18132 phys_copy(src, vir2phys(loc_addr), (phys_bytes) count);
- 18133 }
- 18136 /*===========================================================================*
- 18137 * put_userdata *
- 18138 *===========================================================================*/
- 18139 static void put_userdata(user_proc, user_addr, count, loc_addr)
- 18140 int user_proc;
- 18141 vir_bytes user_addr;
- 18142 vir_bytes count;
- 18143 void *loc_addr;
- 18144 {
- 18145 phys_bytes dst;
- 18146
- 18147 dst = numap(user_proc, user_addr, count);
- 18148 if (!dst)
- 18149 panic("dp8390: umap failed", NO_NUM);
- 18150
- 18151 phys_copy(vir2phys(loc_addr), dst, (phys_bytes) count);
- 18152 }
- 18154 #endif /* ENABLE_NETWORKING */
- 18155
- 18156 /*
- 18157 * $PchHeader: /mount/hd2/minix/sys/kernel/ibm/RCS/dp8390.c,v 1.4 1995/06/13 08:10:42 philip Exp $
- 18158 */
- .Ep 238 src/kernel/driver.c
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- src/kernel/driver.c
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 18200 /* This file contains device independent device driver interface.
- 18201 * Author: Kees J. Bot.
- 18202 *
- 18203 * The drivers support the following operations (using message format m2):
- 18204 *
- 18205 * m_type DEVICE PROC_NR COUNT POSITION ADRRESS
- 18206 * ----------------------------------------------------------------
- 18207 * | DEV_OPEN | device | proc nr | | | |
- 18208 * |------------+---------+---------+---------+---------+---------|
- 18209 * | DEV_CLOSE | device | proc nr | | | |
- 18210 * |------------+---------+---------+---------+---------+---------|
- 18211 * | DEV_READ | device | proc nr | bytes | offset | buf ptr |
- 18212 * |------------+---------+---------+---------+---------+---------|
- 18213 * | DEV_WRITE | device | proc nr | bytes | offset | buf ptr |
- 18214 * |------------+---------+---------+---------+---------+---------|
- 18215 * |SCATTERED_IO| device | proc nr | requests| | iov ptr |
- 18216 * ----------------------------------------------------------------
- 18217 * | DEV_IOCTL | device | proc nr |func code| | buf ptr |
- 18218 * ----------------------------------------------------------------
- 18219 *
- 18220 * The file contains one entry point:
- 18221 *
- 18222 * driver_task: called by the device dependent task entry
- 18223 *
- 18224 *
- 18225 * Constructed 92/04/02 by Kees J. Bot from the old AT wini and floppy driver.
- 18226 */
- 18227
- 18228 #include "kernel.h"
- 18229 #include <sys/ioctl.h>
- 18230 #include "driver.h"
- 18231
- 18232 #if (CHIP == INTEL)
- 18233 #if ENABLE_ADAPTEC_SCSI && DMA_BUF_SIZE < 2048
- 18234 /* A bit extra scratch for the Adaptec driver. */
- 18235 #define BUF_EXTRA (2048 - DMA_BUF_SIZE)
- 18236 #else
- 18237 #define BUF_EXTRA 0
- 18238 #endif
- 18239
- 18240 /* Claim space for variables. */
- 18241 PRIVATE u8_t buffer[(unsigned) 2 * DMA_BUF_SIZE + BUF_EXTRA];
- 18242 u8_t *tmp_buf; /* the DMA buffer eventually */
- 18243 phys_bytes tmp_phys; /* phys address of DMA buffer */
- 18244
- 18245 #else /* CHIP != INTEL */
- 18246
- 18247 /* Claim space for variables. */
- 18248 u8_t tmp_buf[DMA_BUF_SIZE]; /* the DMA buffer */
- 18249 phys_bytes tmp_phys; /* phys address of DMA buffer */
- 18250
- 18251 #endif /* CHIP != INTEL */
- 18252
- 18253 FORWARD _PROTOTYPE( void init_buffer, (void) );
- 18254
- .Op 239 src/kernel/driver.c
- 18255
- 18256 /*===========================================================================*
- 18257 * driver_task *
- 18258 *===========================================================================*/
- 18259 PUBLIC void driver_task(dp)
- 18260 struct driver *dp; /* Device dependent entry points. */
- 18261 {
- 18262 /* Main program of any device driver task. */
- 18263
- 18264 int r, caller, proc_nr;
- 18265 message mess;
- 18266
- 18267 init_buffer(); /* Get a DMA buffer. */
- 18268
- 18269
- 18270 /* Here is the main loop of the disk task. It waits for a message, carries
- 18271 * it out, and sends a reply.
- 18272 */
- 18273
- 18274 while (TRUE) {
- 18275 /* First wait for a request to read or write a disk block. */
- 18276 receive(ANY, &mess);
- 18277
- 18278 caller = mess.m_source;
- 18279 proc_nr = mess.PROC_NR;
- 18280
- 18281 switch (caller) {
- 18282 case HARDWARE:
- 18283 /* Leftover interrupt. */
- 18284 continue;
- 18285 case FS_PROC_NR:
- 18286 /* The only legitimate caller. */
- 18287 break;
- 18288 default:
- 18289 printf("%s: got message from %dn", (*dp->dr_name)(), caller);
- 18290 continue;
- 18291 }
- 18292
- 18293 /* Now carry out the work. */
- 18294 switch(mess.m_type) {
- 18295 case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break;
- 18296 case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break;
- 18297 case DEV_IOCTL: r = (*dp->dr_ioctl)(dp, &mess); break;
- 18298
- 18299 case DEV_READ:
- 18300 case DEV_WRITE: r = do_rdwt(dp, &mess); break;
- 18301
- 18302 case SCATTERED_IO: r = do_vrdwt(dp, &mess); break;
- 18303 default: r = EINVAL; break;
- 18304 }
- 18305
- 18306 /* Clean up leftover state. */
- 18307 (*dp->dr_cleanup)();
- 18308
- 18309 /* Finally, prepare and send the reply message. */
- 18310 mess.m_type = TASK_REPLY;
- 18311 mess.REP_PROC_NR = proc_nr;
- 18312
- 18313 mess.REP_STATUS = r; /* # of bytes transferred or error code */
- 18314 send(caller, &mess); /* send reply to caller */
- .Ep 240 src/kernel/driver.c
- 18315 }
- 18316 }
- 18319 /*===========================================================================*
- 18320 * init_buffer *
- 18321 *===========================================================================*/
- 18322 PRIVATE void init_buffer()
- 18323 {
- 18324 /* Select a buffer that can safely be used for dma transfers. It may also
- 18325 * be used to read partition tables and such. Its absolute address is
- 18326 * 'tmp_phys', the normal address is 'tmp_buf'.
- 18327 */
- 18328
- 18329 #if (CHIP == INTEL)
- 18330 tmp_buf = buffer;
- 18331 tmp_phys = vir2phys(buffer);
- 18332
- 18333 if (tmp_phys == 0) panic("no DMA buffer", NO_NUM);
- 18334
- 18335 if (dma_bytes_left(tmp_phys) < DMA_BUF_SIZE) {
- 18336 /* First half of buffer crosses a 64K boundary, can't DMA into that */
- 18337 tmp_buf += DMA_BUF_SIZE;
- 18338 tmp_phys += DMA_BUF_SIZE;
- 18339 }
- 18340 #else /* CHIP != INTEL */
- 18341 tmp_phys = vir2phys(tmp_buf);
- 18342 #endif /* CHIP != INTEL */
- 18343 }
- 18346 /*===========================================================================*
- 18347 * do_rdwt *
- 18348 *===========================================================================*/
- 18349 PUBLIC int do_rdwt(dp, m_ptr)
- 18350 struct driver *dp; /* device dependent entry points */
- 18351 message *m_ptr; /* pointer to read or write message */
- 18352 {
- 18353 /* Carry out a single read or write request. */
- 18354 struct iorequest_s ioreq;
- 18355 int r;
- 18356
- 18357 if (m_ptr->COUNT <= 0) return(EINVAL);
- 18358
- 18359 if ((*dp->dr_prepare)(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
- 18360
- 18361 ioreq.io_request = m_ptr->m_type;
- 18362 ioreq.io_buf = m_ptr->ADDRESS;
- 18363 ioreq.io_position = m_ptr->POSITION;
- 18364 ioreq.io_nbytes = m_ptr->COUNT;
- 18365
- 18366 r = (*dp->dr_schedule)(m_ptr->PROC_NR, &ioreq);
- 18367
- 18368 if (r == OK) (void) (*dp->dr_finish)();
- 18369
- 18370 r = ioreq.io_nbytes;
- 18371 return(r < 0 ? r : m_ptr->COUNT - r);
- 18372 }
- .Op 241 src/kernel/driver.c
- 18375 /*==========================================================================*
- 18376 * do_vrdwt *
- 18377 *==========================================================================*/
- 18378 PUBLIC int do_vrdwt(dp, m_ptr)
- 18379 struct driver *dp; /* device dependent entry points */
- 18380 message *m_ptr; /* pointer to read or write message */
- 18381 {
- 18382 /* Fetch a vector of i/o requests. Handle requests one at a time. Return
- 18383 * status in the vector.
- 18384 */
- 18385
- 18386 struct iorequest_s *iop;
- 18387 static struct iorequest_s iovec[NR_IOREQS];
- 18388 phys_bytes iovec_phys;
- 18389 unsigned nr_requests;
- 18390 int request;
- 18391 int r;
- 18392 phys_bytes user_iovec_phys;
- 18393
- 18394 nr_requests = m_ptr->COUNT;
- 18395
- 18396 if (nr_requests > sizeof iovec / sizeof iovec[0])
- 18397 panic("FS passed too big an I/O vector", nr_requests);
- 18398
- 18399 iovec_phys = vir2phys(iovec);
- 18400 user_iovec_phys = numap(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS,
- 18401 (vir_bytes) (nr_requests * sizeof iovec[0]));
- 18402
- 18403 if (user_iovec_phys == 0)
- 18404 panic("FS passed a bad I/O vector", (int) m_ptr->ADDRESS);
- 18405
- 18406 phys_copy(user_iovec_phys, iovec_phys,
- 18407 (phys_bytes) nr_requests * sizeof iovec[0]);
- 18408
- 18409 if ((*dp->dr_prepare)(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
- 18410
- 18411 for (request = 0, iop = iovec; request < nr_requests; request++, iop++) {
- 18412 if ((r = (*dp->dr_schedule)(m_ptr->PROC_NR, iop)) != OK) break;
- 18413 }
- 18414
- 18415 if (r == OK) (void) (*dp->dr_finish)();
- 18416
- 18417 phys_copy(iovec_phys, user_iovec_phys,
- 18418 (phys_bytes) nr_requests * sizeof iovec[0]);
- 18419 return(OK);
- 18420 }
- 18423 /*===========================================================================*
- 18424 * no_name *
- 18425 *===========================================================================*/
- 18426 PUBLIC char *no_name()
- 18427 {
- 18428 /* If no specific name for the device. */
- 18429
- 18430 return(tasktab[proc_number(proc_ptr) + NR_TASKS].name);
- 18431 }
- 18434 /*============================================================================*
- .Ep 242 src/kernel/driver.c
- 18435 * do_nop *
- 18436 *============================================================================*/
- 18437 PUBLIC int do_nop(dp, m_ptr)
- 18438 struct driver *dp;
- 18439 message *m_ptr;
- 18440 {
- 18441 /* Nothing there, or nothing to do. */
- 18442
- 18443 switch (m_ptr->m_type) {
- 18444 case DEV_OPEN: return(ENODEV);
- 18445 case DEV_CLOSE: return(OK);
- 18446 case DEV_IOCTL: return(ENOTTY);
- 18447 default: return(EIO);
- 18448 }
- 18449 }
- 18452 /*===========================================================================*
- 18453 * nop_finish *
- 18454 *===========================================================================*/
- 18455 PUBLIC int nop_finish()
- 18456 {
- 18457 /* Nothing to finish, all the work has been done by dp->dr_schedule. */
- 18458 return(OK);
- 18459 }
- 18462 /*===========================================================================*
- 18463 * nop_cleanup *
- 18464 *===========================================================================*/
- 18465 PUBLIC void nop_cleanup()
- 18466 {
- 18467 /* Nothing to clean up. */
- 18468 }
- 18471 /*===========================================================================*
- 18472 * clock_mess *
- 18473 *===========================================================================*/
- 18474 PUBLIC void clock_mess(ticks, func)
- 18475 int ticks; /* how many clock ticks to wait */
- 18476 watchdog_t func; /* function to call upon time out */
- 18477 {
- 18478 /* Send the clock task a message. */
- 18479
- 18480 message mess;
- 18481
- 18482 mess.m_type = SET_ALARM;
- 18483 mess.CLOCK_PROC_NR = proc_number(proc_ptr);
- 18484 mess.DELTA_TICKS = (long) ticks;
- 18485 mess.FUNC_TO_CALL = (sighandler_t) func;
- 18486 sendrec(CLOCK, &mess);
- 18487 }
- 18490 /*============================================================================*
- 18491 * do_diocntl *
- 18492 *============================================================================*/
- 18493 PUBLIC int do_diocntl(dp, m_ptr)
- 18494 struct driver *dp;
- .Op 243 src/kernel/driver.c
- 18495 message *m_ptr; /* pointer to ioctl request */
- 18496 {
- 18497 /* Carry out a partition setting/getting request. */
- 18498 struct device *dv;
- 18499 phys_bytes user_phys, entry_phys;
- 18500 struct partition entry;
- 18501
- 18502 if (m_ptr->REQUEST != DIOCSETP && m_ptr->REQUEST != DIOCGETP) return(ENOTTY);
- 18503
- 18504 /* Decode the message parameters. */
- 18505 if ((dv = (*dp->dr_prepare)(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
- 18506
- 18507 user_phys = numap(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS, sizeof(entry));
- 18508 if (user_phys == 0) return(EFAULT);
- 18509
- 18510 entry_phys = vir2phys(&entry);
- 18511
- 18512 if (m_ptr->REQUEST == DIOCSETP) {
- 18513 /* Copy just this one partition table entry. */
- 18514 phys_copy(user_phys, entry_phys, (phys_bytes) sizeof(entry));
- 18515 dv->dv_base = entry.base;
- 18516 dv->dv_size = entry.size;
- 18517 } else {
- 18518 /* Return a partition table entry and the geometry of the drive. */
- 18519 entry.base = dv->dv_base;
- 18520 entry.size = dv->dv_size;
- 18521 (*dp->dr_geometry)(&entry);
- 18522 phys_copy(entry_phys, user_phys, (phys_bytes) sizeof(entry));
- 18523 }
- 18524 return(OK);
- 18525 }
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- src/kernel/drvlib.c
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 18600 /* IBM device driver utility functions. Author: Kees J. Bot
- 18601 * 7 Dec 1995
- 18602 * Entry point:
- 18603 * partition: partition a disk to the partition table(s) on it.
- 18604 */
- 18605
- 18606 #include "kernel.h"
- 18607 #include "driver.h"
- 18608 #include "drvlib.h"
- 18609
- 18610
- 18611 FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
- 18612 unsigned long extbase) );
- 18613 FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
- 18614 unsigned long offset, struct part_entry *table) );
- 18615 FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
- 18616
- 18617
- 18618 /*============================================================================*
- 18619 * partition *
- .Ep 244 src/kernel/drvlib.c
- 18620 *============================================================================*/
- 18621 PUBLIC void partition(dp, device, style)
- 18622 struct driver *dp; /* device dependent entry points */
- 18623 int device; /* device to partition */
- 18624 int style; /* partitioning style: floppy, primary, sub. */
- 18625 {
- 18626 /* This routine is called on first open to initialize the partition tables
- 18627 * of a device. It makes sure that each partition falls safely within the
- 18628 * device's limits. Depending on the partition style we are either making
- 18629 * floppy partitions, primary partitions or subpartitions. Only primary
- 18630 * partitions are sorted, because they are shared with other operating
- 18631 * systems that expect this.
- 18632 */
- 18633 struct part_entry table[NR_PARTITIONS], *pe;
- 18634 int disk, par;
- 18635 struct device *dv;
- 18636 unsigned long base, limit, part_limit;
- 18637
- 18638 /* Get the geometry of the device to partition */
- 18639 if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV || dv->dv_size == 0) return;
- 18640 base = dv->dv_base >> SECTOR_SHIFT;
- 18641 limit = base + (dv->dv_size >> SECTOR_SHIFT);
- 18642
- 18643 /* Read the partition table for the device. */
- 18644 if (!get_part_table(dp, device, 0L, table)) return;
- 18645
- 18646 /* Compute the device number of the first partition. */
- 18647 switch (style) {
- 18648 case P_FLOPPY:
- 18649 device += MINOR_fd0a;
- 18650 break;
- 18651 case P_PRIMARY:
- 18652 sort(table); /* sort a primary partition table */
- 18653 device += 1;
- 18654 break;
- 18655 case P_SUB:
- 18656 disk = device / DEV_PER_DRIVE;
- 18657 par = device % DEV_PER_DRIVE - 1;
- 18658 device = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
- 18659 }
- 18660
- 18661 /* Find an array of devices. */
- 18662 if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV) return;
- 18663
- 18664 /* Set the geometry of the partitions from the partition table. */
- 18665 for (par = 0; par < NR_PARTITIONS; par++, dv++) {
- 18666 /* Shrink the partition to fit within the device. */
- 18667 pe = &table[par];
- 18668 part_limit = pe->lowsec + pe->size;
- 18669 if (part_limit < pe->lowsec) part_limit = limit;
- 18670 if (part_limit > limit) part_limit = limit;
- 18671 if (pe->lowsec < base) pe->lowsec = base;
- 18672 if (part_limit < pe->lowsec) part_limit = pe->lowsec;
- 18673
- 18674 dv->dv_base = pe->lowsec << SECTOR_SHIFT;
- 18675 dv->dv_size = (part_limit - pe->lowsec) << SECTOR_SHIFT;
- 18676
- 18677 if (style == P_PRIMARY) {
- 18678 /* Each Minix primary partition can be subpartitioned. */
- 18679 if (pe->sysind == MINIX_PART)
- .Op 245 src/kernel/drvlib.c
- 18680 partition(dp, device + par, P_SUB);
- 18681
- 18682 /* An extended partition has logical partitions. */
- 18683 if (pe->sysind == EXT_PART)
- 18684 extpartition(dp, device + par, pe->lowsec);
- 18685 }
- 18686 }
- 18687 }
- 18690 /*============================================================================*
- 18691 * extpartition *
- 18692 *============================================================================*/
- 18693 PRIVATE void extpartition(dp, extdev, extbase)
- 18694 struct driver *dp; /* device dependent entry points */
- 18695 int extdev; /* extended partition to scan */
- 18696 unsigned long extbase; /* sector offset of the base extended partition */
- 18697 {
- 18698 /* Extended partitions cannot be ignored alas, because people like to move
- 18699 * files to and from DOS partitions. Avoid reading this code, it's no fun.
- 18700 */
- 18701 struct part_entry table[NR_PARTITIONS], *pe;
- 18702 int subdev, disk, par;
- 18703 struct device *dv;
- 18704 unsigned long offset, nextoffset;
- 18705
- 18706 disk = extdev / DEV_PER_DRIVE;
- 18707 par = extdev % DEV_PER_DRIVE - 1;
- 18708 subdev = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
- 18709
- 18710 offset = 0;
- 18711 do {
- 18712 if (!get_part_table(dp, extdev, offset, table)) return;
- 18713 sort(table);
- 18714
- 18715 /* The table should contain one logical partition and optionally
- 18716 * another extended partition. (It's a linked list.)
- 18717 */
- 18718 nextoffset = 0;
- 18719 for (par = 0; par < NR_PARTITIONS; par++) {
- 18720 pe = &table[par];
- 18721 if (pe->sysind == EXT_PART) {
- 18722 nextoffset = pe->lowsec;
- 18723 } else
- 18724 if (pe->sysind != NO_PART) {
- 18725 if ((dv = (*dp->dr_prepare)(subdev)) == NIL_DEV) return;
- 18726
- 18727 dv->dv_base = (extbase + offset
- 18728 + pe->lowsec) << SECTOR_SHIFT;
- 18729 dv->dv_size = pe->size << SECTOR_SHIFT;
- 18730
- 18731 /* Out of devices? */
- 18732 if (++subdev % NR_PARTITIONS == 0) return;
- 18733 }
- 18734 }
- 18735 } while ((offset = nextoffset) != 0);
- 18736 }
- 18739 /*============================================================================*
- .Ep 246 src/kernel/drvlib.c
- 18740 * get_part_table *
- 18741 *============================================================================*/
- 18742 PRIVATE int get_part_table(dp, device, offset, table)
- 18743 struct driver *dp;
- 18744 int device;
- 18745 unsigned long offset; /* sector offset to the table */
- 18746 struct part_entry *table; /* four entries */
- 18747 {
- 18748 /* Read the partition table for the device, return true iff there were no
- 18749 * errors.
- 18750 */