COMPLETE.TXT
上传用户:jnzhq888
上传日期:2007-01-18
资源大小:51694k
文件大小:2624k
源码类别:

操作系统开发

开发平台:

WINDOWS

  1. 15729                                 /* Set the blink bit */
  2. 15730                                 cons->c_attr |= 0x8000;
  3. 15731                         }
  4. 15732                         break;
  5. 15733
  6. 15734                     case 7:     /* REVERSE */
  7. 15735                         if (color) {
  8. 15736                                 /* Swap fg and bg colors */
  9. 15737                                 cons->c_attr =
  10. 15738                                         ((cons->c_attr & 0xf000) >> 4) |
  11. 15739                                         ((cons->c_attr & 0x0f00) << 4);
  12. 15740                         } else
  13. 15741                         if ((cons->c_attr & 0x7000) == 0) {
  14. 15742                                 cons->c_attr = (cons->c_attr & 0x8800) | 0x7000;
  15. 15743                         } else {
  16. 15744                                 cons->c_attr = (cons->c_attr & 0x8800) | 0x0700;
  17. 15745                         }
  18. 15746                         break;
  19. 15747
  20. 15748                     default:    /* COLOR */
  21. 15749                         if (30 <= value && value <= 37) {
  22. 15750                                 cons->c_attr =
  23. 15751                                         (cons->c_attr & 0xf0ff) |
  24. 15752                                         (ansi_colors[(value - 30)] << 8);
  25. 15753                                 cons->c_blank =
  26. 15754                                         (cons->c_blank & 0xf0ff) |
  27. 15755                                         (ansi_colors[(value - 30)] << 8);
  28. 15756                         } else
  29. 15757                         if (40 <= value && value <= 47) {
  30. 15758                                 cons->c_attr =
  31. 15759                                         (cons->c_attr & 0x0fff) |
  32. 15760                                         (ansi_colors[(value - 40)] << 12);
  33. 15761                                 cons->c_blank =
  34. 15762                                         (cons->c_blank & 0x0fff) |
  35. 15763                                         (ansi_colors[(value - 40)] << 12);
  36. 15764                         } else {
  37. 15765                                 cons->c_attr = cons->c_blank;
  38. 15766                         }
  39. 15767                         break;
  40. 15768                 }
  41. 15769                 break;
  42. 15770         }
  43. 15771   }
  44. 15772   cons->c_esc_state = 0;
  45. 15773 }
  46. 15776 /*===========================================================================*
  47. 15777  *                              set_6845                                     *
  48. 15778  *===========================================================================*/
  49. 15779 PRIVATE void set_6845(reg, val)
  50. 15780 int reg;                        /* which register pair to set */
  51. 15781 unsigned val;                   /* 16-bit value to set it to */
  52. 15782 {
  53. 15783 /* Set a register pair inside the 6845.
  54. 15784  * Registers 12-13 tell the 6845 where in video ram to start
  55. 15785  * Registers 14-15 tell the 6845 where to put the cursor
  56. 15786  */
  57. 15787   lock();                       /* try to stop h/w loading in-between value */
  58. 15788   out_byte(vid_port + INDEX, reg);              /* set the index register */
  59. 15789   out_byte(vid_port + DATA, (val>>8) & BYTE);   /* output high byte */
  60. 15790   out_byte(vid_port + INDEX, reg + 1);          /* again */
  61. 15791   out_byte(vid_port + DATA, val&BYTE);          /* output low byte */
  62. 15792   unlock();
  63. 15793 }
  64. 15796 /*===========================================================================*
  65. 15797  *                              beep                                         *
  66. 15798  *===========================================================================*/
  67. 15799 PRIVATE void beep()
  68. 15800 {
  69. 15801 /* Making a beeping sound on the speaker (output for CRTL-G).
  70. 15802  * This routine works by turning on the bits 0 and 1 in port B of the 8255
  71. 15803  * chip that drive the speaker.
  72. 15804  */
  73. 15805
  74. 15806   message mess;
  75. 15807
  76. 15808   if (beeping) return;
  77. 15809   out_byte(TIMER_MODE, 0xB6);   /* set up timer channel 2 (square wave) */
  78. 15810   out_byte(TIMER2, BEEP_FREQ & BYTE);   /* load low-order bits of frequency */
  79. 15811   out_byte(TIMER2, (BEEP_FREQ >> 8) & BYTE);    /* now high-order bits */
  80. 15812   lock();                       /* guard PORT_B from keyboard intr handler */
  81. 15813   out_byte(PORT_B, in_byte(PORT_B) | 3);        /* turn on beep bits */
  82. 15814   unlock();
  83. 15815   beeping = TRUE;
  84. 15816
  85. 15817   mess.m_type = SET_ALARM;
  86. 15818   mess.CLOCK_PROC_NR = TTY;
  87. 15819   mess.DELTA_TICKS = B_TIME;
  88. 15820   mess.FUNC_TO_CALL = (sighandler_t) stop_beep;
  89. 15821   sendrec(CLOCK, &mess);
  90. 15822 }
  91. 15825 /*===========================================================================*
  92. 15826  *                              stop_beep                                    *
  93. 15827  *===========================================================================*/
  94. 15828 PRIVATE void stop_beep()
  95. 15829 {
  96. 15830 /* Turn off the beeper by turning off bits 0 and 1 in PORT_B. */
  97. 15831
  98. 15832   lock();                       /* guard PORT_B from keyboard intr handler */
  99. 15833   out_byte(PORT_B, in_byte(PORT_B) & ~3);
  100. 15834   beeping = FALSE;
  101. 15835   unlock();
  102. 15836 }
  103. 15839 /*===========================================================================*
  104. 15840  *                              scr_init                                     *
  105. 15841  *===========================================================================*/
  106. 15842 PUBLIC void scr_init(tp)
  107. 15843 tty_t *tp;
  108. 15844 {
  109. 15845 /* Initialize the screen driver. */
  110. 15846   console_t *cons;
  111. 15847   phys_bytes vid_base;
  112. 15848   u16_t bios_crtbase;
  113. 15849   int line;
  114. 15850   unsigned page_size;
  115. 15851
  116. 15852   /* Associate console and TTY. */
  117. 15853   line = tp - &tty_table[0];
  118. 15854   if (line >= nr_cons) return;
  119. 15855   cons = &cons_table[line];
  120. 15856   cons->c_tty = tp;
  121. 15857   tp->tty_priv = cons;
  122. 15858
  123. 15859   /* Initialize the keyboard driver. */
  124. 15860   kb_init(tp);
  125. 15861
  126. 15862   /* Output functions. */
  127. 15863   tp->tty_devwrite = cons_write;
  128. 15864   tp->tty_echo = cons_echo;
  129. 15865
  130. 15866   /* Get the BIOS parameters that tells the VDU I/O base register. */
  131. 15867   phys_copy(0x463L, vir2phys(&bios_crtbase), 2L);
  132. 15868
  133. 15869   vid_port = bios_crtbase;
  134. 15870
  135. 15871   if (color) {
  136. 15872         vid_base = COLOR_BASE;
  137. 15873         vid_size = COLOR_SIZE;
  138. 15874   } else {
  139. 15875         vid_base = MONO_BASE;
  140. 15876         vid_size = MONO_SIZE;
  141. 15877   }
  142. 15878   if (ega) vid_size = EGA_SIZE;
  143. 15879   wrap = !ega;
  144. 15880
  145. 15881   vid_seg = protected_mode ? VIDEO_SELECTOR : physb_to_hclick(vid_base);
  146. 15882   init_dataseg(&gdt[VIDEO_INDEX], vid_base, (phys_bytes) vid_size,
  147. 15883                                                         TASK_PRIVILEGE);
  148. 15884   vid_size >>= 1;               /* word count */
  149. 15885   vid_mask = vid_size - 1;
  150. 15886
  151. 15887   /* There can be as many consoles as video memory allows. */
  152. 15888   nr_cons = vid_size / scr_size;
  153. 15889   if (nr_cons > NR_CONS) nr_cons = NR_CONS;
  154. 15890   if (nr_cons > 1) wrap = 0;
  155. 15891   page_size = vid_size / nr_cons;
  156. 15892   cons->c_start = line * page_size;
  157. 15893   cons->c_limit = cons->c_start + page_size;
  158. 15894   cons->c_org = cons->c_start;
  159. 15895   cons->c_attr = cons->c_blank = BLANK_COLOR;
  160. 15896
  161. 15897   /* Clear the screen. */
  162. 15898   blank_color = BLANK_COLOR;
  163. 15899   mem_vid_copy(BLANK_MEM, cons->c_start, scr_size);
  164. 15900   select_console(0);
  165. 15901 }
  166. 15904 /*===========================================================================*
  167. 15905  *                              putk                                         *
  168. 15906  *===========================================================================*/
  169. 15907 PUBLIC void putk(c)
  170. 15908 int c;                          /* character to print */
  171. 15909 {
  172. 15910 /* This procedure is used by the version of printf() that is linked with
  173. 15911  * the kernel itself.  The one in the library sends a message to FS, which is
  174. 15912  * not what is needed for printing within the kernel.  This version just queues
  175. 15913  * the character and starts the output.
  176. 15914  */
  177. 15915
  178. 15916   if (c != 0) {
  179. 15917         if (c == 'n') putk('r');
  180. 15918         out_char(&cons_table[0], (int) c);
  181. 15919   } else {
  182. 15920         flush(&cons_table[0]);
  183. 15921   }
  184. 15922 }
  185. 15925 /*===========================================================================*
  186. 15926  *                              toggle_scroll                                *
  187. 15927  *===========================================================================*/
  188. 15928 PUBLIC void toggle_scroll()
  189. 15929 {
  190. 15930 /* Toggle between hardware and software scroll. */
  191. 15931
  192. 15932   cons_org0();
  193. 15933   softscroll = !softscroll;
  194. 15934   printf("%sware scrolling enabled.n", softscroll ? "Soft" : "Hard");
  195. 15935 }
  196. 15938 /*===========================================================================*
  197. 15939  *                              cons_stop                                    *
  198. 15940  *===========================================================================*/
  199. 15941 PUBLIC void cons_stop()
  200. 15942 {
  201. 15943 /* Prepare for halt or reboot. */
  202. 15944   cons_org0();
  203. 15945   softscroll = 1;
  204. 15946   select_console(0);
  205. 15947   cons_table[0].c_attr = cons_table[0].c_blank = BLANK_COLOR;
  206. 15948 }
  207. 15951 /*===========================================================================*
  208. 15952  *                              cons_org0                                    *
  209. 15953  *===========================================================================*/
  210. 15954 PRIVATE void cons_org0()
  211. 15955 {
  212. 15956 /* Scroll video memory back to put the origin at 0. */
  213. 15957   int cons_line;
  214. 15958   console_t *cons;
  215. 15959   unsigned n;
  216. 15960
  217. 15961   for (cons_line = 0; cons_line < nr_cons; cons_line++) {
  218. 15962         cons = &cons_table[cons_line];
  219. 15963         while (cons->c_org > cons->c_start) {
  220. 15964                 n = vid_size - scr_size;        /* amount of unused memory */
  221. 15965                 if (n > cons->c_org - cons->c_start)
  222. 15966                         n = cons->c_org - cons->c_start;
  223. 15967                 vid_vid_copy(cons->c_org, cons->c_org - n, scr_size);
  224. 15968                 cons->c_org -= n;
  225. 15969         }
  226. 15970         flush(cons);
  227. 15971   }
  228. 15972   select_console(current);
  229. 15973 }
  230. 15976 /*===========================================================================*
  231. 15977  *                              select_console                               *
  232. 15978  *===========================================================================*/
  233. 15979 PUBLIC void select_console(int cons_line)
  234. 15980 {
  235. 15981 /* Set the current console to console number 'cons_line'. */
  236. 15982
  237. 15983   if (cons_line < 0 || cons_line >= nr_cons) return;
  238. 15984   current = cons_line;
  239. 15985   curcons = &cons_table[cons_line];
  240. 15986   set_6845(VID_ORG, curcons->c_org);
  241. 15987   set_6845(CURSOR, curcons->c_cur);
  242. 15988 }
  243. 15991 /*===========================================================================*
  244. 15992  *                              con_loadfont                                 *
  245. 15993  *===========================================================================*/
  246. 15994
  247. 15995 PUBLIC int con_loadfont(user_phys)
  248. 15996 phys_bytes user_phys;
  249. 15997 {
  250. 15998 /* Load a font into the EGA or VGA adapter. */
  251. 15999   static struct sequence seq1[7] = {
  252. 16000         { GA_SEQUENCER_INDEX, 0x00, 0x01 },
  253. 16001         { GA_SEQUENCER_INDEX, 0x02, 0x04 },
  254. 16002         { GA_SEQUENCER_INDEX, 0x04, 0x07 },
  255. 16003         { GA_SEQUENCER_INDEX, 0x00, 0x03 },
  256. 16004         { GA_GRAPHICS_INDEX, 0x04, 0x02 },
  257. 16005         { GA_GRAPHICS_INDEX, 0x05, 0x00 },
  258. 16006         { GA_GRAPHICS_INDEX, 0x06, 0x00 },
  259. 16007   };
  260. 16008   static struct sequence seq2[7] = {
  261. 16009         { GA_SEQUENCER_INDEX, 0x00, 0x01 },
  262. 16010         { GA_SEQUENCER_INDEX, 0x02, 0x03 },
  263. 16011         { GA_SEQUENCER_INDEX, 0x04, 0x03 },
  264. 16012         { GA_SEQUENCER_INDEX, 0x00, 0x03 },
  265. 16013         { GA_GRAPHICS_INDEX, 0x04, 0x00 },
  266. 16014         { GA_GRAPHICS_INDEX, 0x05, 0x10 },
  267. 16015         { GA_GRAPHICS_INDEX, 0x06,    0 },
  268. 16016   };
  269. 16017
  270. 16018   seq2[6].value= color ? 0x0E : 0x0A;
  271. 16019
  272. 16020   if (!ega) return(ENOTTY);
  273. 16021
  274. 16022   lock();
  275. 16023   ga_program(seq1);     /* bring font memory into view */
  276. 16024
  277. 16025   phys_copy(user_phys, (phys_bytes)GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);
  278. 16026
  279. 16027   ga_program(seq2);     /* restore */
  280. 16028   unlock();
  281. 16029
  282. 16030   return(OK);
  283. 16031 }
  284. 16034 /*===========================================================================*
  285. 16035  *                              ga_program                                   *
  286. 16036  *===========================================================================*/
  287. 16037
  288. 16038 PRIVATE void ga_program(seq)
  289. 16039 struct sequence *seq;
  290. 16040 {
  291. 16041   int len= 7;
  292. 16042   do {
  293. 16043         out_byte(seq->index, seq->port);
  294. 16044         out_byte(seq->index+1, seq->value);
  295. 16045         seq++;
  296. 16046   } while (--len > 0);
  297. 16047 }
  298. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  299. src/kernel/dmp.c    
  300. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  301. 16100 /* This file contains some dumping routines for debugging. */
  302. 16101
  303. 16102 #include "kernel.h"
  304. 16103 #include <minix/com.h>
  305. 16104 #include "proc.h"
  306. 16105
  307. 16106 char *vargv;
  308. 16107
  309. 16108 FORWARD _PROTOTYPE(char *proc_name, (int proc_nr));
  310. 16109
  311. 16110 /*===========================================================================*
  312. 16111  *                              p_dmp                                        *
  313. 16112  *===========================================================================*/
  314. 16113 #if (CHIP == INTEL)
  315. 16114 PUBLIC void p_dmp()
  316. 16115 {
  317. 16116 /* Proc table dump */
  318. 16117
  319. 16118   register struct proc *rp;
  320. 16119   static struct proc *oldrp = BEG_PROC_ADDR;
  321. 16120   int n = 0;
  322. 16121   phys_clicks text, data, size;
  323. 16122   int proc_nr;
  324. 16123
  325. 16124   printf("n--pid --pc- ---sp- flag -user --sys-- -text- -data- -size- -recv- commandn");
  326. 16125
  327. 16126   for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
  328. 16127         proc_nr = proc_number(rp);
  329. 16128         if (rp->p_flags & P_SLOT_FREE) continue;
  330. 16129         if (++n > 20) break;
  331. 16130         text = rp->p_map[T].mem_phys;
  332. 16131         data = rp->p_map[D].mem_phys;
  333. 16132         size = rp->p_map[T].mem_len
  334. 16133                 + ((rp->p_map[S].mem_phys + rp->p_map[S].mem_len) - data);
  335. 16134         printf("%5d %5lx %6lx %2x %7U %7U %5uK %5uK %5uK ",
  336. 16135                proc_nr < 0 ? proc_nr : rp->p_pid,
  337. 16136                (unsigned long) rp->p_reg.pc,
  338. 16137                (unsigned long) rp->p_reg.sp,
  339. 16138                rp->p_flags,
  340. 16139                rp->user_time, rp->sys_time,
  341. 16140                click_to_round_k(text), click_to_round_k(data),
  342. 16141                click_to_round_k(size));
  343. 16142         if (rp->p_flags & RECEIVING) {
  344. 16143                 printf("%-7.7s", proc_name(rp->p_getfrom));
  345. 16144         } else
  346. 16145         if (rp->p_flags & SENDING) {
  347. 16146                 printf("S:%-5.5s", proc_name(rp->p_sendto));
  348. 16147         } else
  349. 16148         if (rp->p_flags == 0) {
  350. 16149                 printf("       ");
  351. 16150         }
  352. 16151         printf("%sn", rp->p_name);
  353. 16152   }
  354. 16153   if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--r");
  355. 16154   oldrp = rp;
  356. 16155 }
  357. 16156 #endif                          /* (CHIP == INTEL) */
  358. 16157
  359. 16158 /*===========================================================================*
  360. 16159  *                              map_dmp                                      *
  361. 16160  *===========================================================================*/
  362. 16161 #if (SHADOWING == 0)
  363. 16162 PUBLIC void map_dmp()
  364. 16163 {
  365. 16164   register struct proc *rp;
  366. 16165   static struct proc *oldrp = cproc_addr(HARDWARE);
  367. 16166   int n = 0;
  368. 16167   phys_clicks size;
  369. 16168
  370. 16169   printf("nPROC NAME-  -----TEXT-----  -----DATA-----  ----STACK-----  -SIZE-n");
  371. 16170   for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
  372. 16171         if (rp->p_flags & P_SLOT_FREE) continue;
  373. 16172         if (++n > 20) break;
  374. 16173         size = rp->p_map[T].mem_len
  375. 16174                 + ((rp->p_map[S].mem_phys + rp->p_map[S].mem_len)
  376. 16175                                                 - rp->p_map[D].mem_phys);
  377. 16176         printf("%3d %-6.6s  %4x %4x %4x  %4x %4x %4x  %4x %4x %4x  %5uKn",
  378. 16177                proc_number(rp),
  379. 16178                rp->p_name,
  380. 16179                rp->p_map[T].mem_vir, rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
  381. 16180                rp->p_map[D].mem_vir, rp->p_map[D].mem_phys, rp->p_map[D].mem_len,
  382. 16181                rp->p_map[S].mem_vir, rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
  383. 16182                click_to_round_k(size));
  384. 16183   }
  385. 16184   if (rp == END_PROC_ADDR) rp = cproc_addr(HARDWARE); else printf("--more--r");
  386. 16185   oldrp = rp;
  387. 16186 }
  388. 16188 #else
  389. 16189
  390. 16190 PUBLIC void map_dmp()
  391. 16191 {
  392. 16192   register struct proc *rp;
  393. 16193   static struct proc *oldrp = cproc_addr(HARDWARE);
  394. 16194   int n = 0;
  395. 16195   vir_clicks base, limit;
  396. 16196
  397. 16197   printf("nPROC NAME-  --TEXT---  --DATA---  --STACK-- SHADOW FLIP P BASE  SIZEn");
  398. 16198   for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
  399. 16199         if (rp->p_flags & P_SLOT_FREE) continue;
  400. 16200         if (++n > 20) break;
  401. 16201         base = rp->p_map[T].mem_phys;
  402. 16202         limit = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
  403. 16203         printf("%3d %-6.6s  %4x %4x  %4x %4x  %4x %4x   %4x %4d %d %4uKn",
  404. 16204                proc_number(rp),
  405. 16205                rp->p_name,
  406. 16206                rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
  407. 16207                rp->p_map[D].mem_phys, rp->p_map[D].mem_len,
  408. 16208                rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
  409. 16209                rp->p_shadow, rp->p_nflips, rp->p_physio,
  410. 16210                click_to_round_k(base), click_to_round_k(limit));
  411. 16211   }
  412. 16212   if (rp == END_PROC_ADDR) rp = cproc_addr(HARDWARE); else printf("--more--r");
  413. 16213   oldrp = rp;
  414. 16214 }
  415. 16216 #endif
  416. 16217
  417. 16218 #if (CHIP == M68000)
  418. 16219 FORWARD _PROTOTYPE(void mem_dmp, (char *adr, int len));
  419. 16220
  420. 16221 /*===========================================================================*
  421. 16222  *                              p_dmp                                        *
  422. 16223  *===========================================================================*/
  423. 16224 PUBLIC void p_dmp()
  424. 16225 {
  425. 16226 /* Proc table dump */
  426. 16227
  427. 16228   register struct proc *rp;
  428. 16229   static struct proc *oldrp = BEG_PROC_ADDR;
  429. 16230   int n = 0;
  430. 16231   vir_clicks base, limit;
  431. 16232
  432. 16233   printf(
  433. 16234          "nproc pid     pc     sp  splow flag  user    sys   recv   commandn");
  434. 16235
  435. 16236   for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
  436. 16237         if (rp->p_flags & P_SLOT_FREE) continue;
  437. 16238         if (++n > 20) break;
  438. 16239         base = rp->p_map[T].mem_phys;
  439. 16240         limit = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
  440. 16241         printf("%4u %4u %6lx %6lx %6lx %4x %5U %6U   ",
  441. 16242                proc_number(rp),
  442. 16243                rp->p_pid,
  443. 16244                (unsigned long) rp->p_reg.pc,
  444. 16245                (unsigned long) rp->p_reg.sp,
  445. 16246                (unsigned long) rp->p_splow,
  446. 16247                rp->p_flags,
  447. 16248                rp->user_time, rp->sys_time);
  448. 16249         if (rp->p_flags & RECEIVING) {
  449. 16250                 printf("%-7.7s", proc_name(rp->p_getfrom));
  450. 16251         } else
  451. 16252         if (rp->p_flags & SENDING) {
  452. 16253                 printf("S:%-5.5s", proc_name(rp->p_sendto));
  453. 16254         } else
  454. 16255         if (rp->p_flags == 0) {
  455. 16256                 printf("       ");
  456. 16257         }
  457. 16258         printf("%sn", rp->p_name);
  458. 16259   }
  459. 16260   if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--r");
  460. 16261   oldrp = rp;
  461. 16262 }
  462. 16265 /*===========================================================================*
  463. 16266  *                              reg_dmp                                      *
  464. 16267  *===========================================================================*/
  465. 16268 PUBLIC void reg_dmp(rp)
  466. 16269 struct proc *rp;
  467. 16270 {
  468. 16271   register int i;
  469. 16272   static char *regs[NR_REGS] = {
  470. 16273                     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  471. 16274                     "a0", "a1", "a2", "a3", "a4", "a5", "a6"
  472. 16275   };
  473. 16276   reg_t *regptr = (reg_t *) & rp->p_reg;
  474. 16277
  475. 16278   printf("reg = %08lx, ", rp);
  476. 16279   printf("ksp = %08lxn", (long) &rp + sizeof(rp));
  477. 16280   printf(" pc = %08lx, ", rp->p_reg.pc);
  478. 16281   printf(" sr =     %04x, ", rp->p_reg.psw);
  479. 16282   printf("trp =       %2xn", rp->p_trap);
  480. 16283   for (i = 0; i < NR_REGS; i++) 
  481. 16284         printf("%3s = %08lx%s",regs[i], *regptr++, (i&3) == 3 ? "n" : ", ");
  482. 16285   printf(" a7 = %08lxn", rp->p_reg.sp);
  483. 16286 #if (SHADOWING == 1)
  484. 16287     mem_dmp((char *) (((long) rp->p_reg.pc & ~31L) - 96), 128);
  485. 16288     mem_dmp((char *) (((long) rp->p_reg.sp & ~31L) - 32), 256);
  486. 16289 #else
  487. 16290     mem_dmp((char *) (((long) rp->p_reg.pc & ~31L) - 96 +
  488. 16291                         ((long)rp->p_map[T].mem_phys<<CLICK_SHIFT)), 128);
  489. 16292     mem_dmp((char *) (((long) rp->p_reg.sp & ~31L) - 32 +
  490. 16293                         ((long)rp->p_map[S].mem_phys<<CLICK_SHIFT)), 256);
  491. 16294 #endif
  492. 16295 }
  493. 16298 /*===========================================================================*
  494. 16299  *                              mem_dmp                                      *
  495. 16300  *===========================================================================*/
  496. 16301 PRIVATE void mem_dmp(adr, len)
  497. 16302 char *adr;
  498. 16303 int len;
  499. 16304 {
  500. 16305   register i;
  501. 16306   register long *p;
  502. 16307
  503. 16308   for (i = 0, p = (long *) adr; i < len; i += 4) {
  504. 16309 #if (CHIP == M68000)
  505. 16310         if ((i & 31) == 0) printf("n%lX:", p);
  506. 16311         printf(" %8lX", *p++);
  507. 16312 #else
  508. 16313         if ((i & 31) == 0) printf("n%X:", p);
  509. 16314         printf(" %8X", *p++);
  510. 16315 #endif /* (CHIP == M68000) */
  511. 16316   }
  512. 16317   printf("n");
  513. 16318 }
  514. 16320 #endif                          /* (CHIP == M68000) */
  515. 16321
  516. 16322
  517. 16323 /*===========================================================================*
  518. 16324  *                              proc_name                                    *
  519. 16325  *===========================================================================*/
  520. 16326 PRIVATE char *proc_name(proc_nr)
  521. 16327 int proc_nr;
  522. 16328 {
  523. 16329   if (proc_nr == ANY) return "ANY";
  524. 16330   return proc_addr(proc_nr)->p_name;
  525. 16331 }
  526. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  527. src/kernel/dp8390.c    
  528. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  529. 16400 /*
  530. 16401  * dp8390.c
  531. 16402  *
  532. 16403  * This file contains a ethernet device driver for NS dp8390 based ethernet
  533. 16404  * cards.
  534. 16405  *
  535. 16406  * The valid messages and their parameters are:
  536. 16407  *
  537. 16408  *   m_type       DL_PORT    DL_PROC   DL_COUNT   DL_MODE   DL_ADDR
  538. 16409  * |------------+----------+---------+----------+---------+---------|
  539. 16410  * | HARDINT    |          |         |          |         |         |
  540. 16411  * |------------|----------|---------|----------|---------|---------|
  541. 16412  * | DL_WRITE   | port nr  | proc nr | count    | mode    | address |
  542. 16413  * |------------|----------|---------|----------|---------|---------|
  543. 16414  * | DL_WRITEV  | port nr  | proc nr | count    | mode    | address |
  544. 16415  * |------------|----------|---------|----------|---------|---------|
  545. 16416  * | DL_READ    | port nr  | proc nr | count    |         | address |
  546. 16417  * |------------|----------|---------|----------|---------|---------|
  547. 16418  * | DL_READV   | port nr  | proc nr | count    |         | address |
  548. 16419  * |------------|----------|---------|----------|---------|---------|
  549. 16420  * | DL_INIT    | port nr  | proc nr | mode     |         | address |
  550. 16421  * |------------|----------|---------|----------|---------|---------|
  551. 16422  * | DL_GETSTAT | port nr  | proc nr |          |         | address |
  552. 16423  * |------------|----------|---------|----------|---------|---------|
  553. 16424  * | DL_STOP    | port_nr  |         |          |         |         |
  554. 16425  * |------------|----------|---------|----------|---------|---------|
  555. 16426  *
  556. 16427  * The messages sent are:
  557. 16428  *
  558. 16429  *   m-type       DL_POR T   DL_PROC   DL_COUNT   DL_STAT   DL_CLCK
  559. 16430  * |------------|----------|---------|----------|---------|---------|
  560. 16431  * |DL_TASK_REPL| port nr  | proc nr | rd-count | err|stat| clock   |
  561. 16432  * |------------|----------|---------|----------|---------|---------|
  562. 16433  *
  563. 16434  *   m_type       m3_i1     m3_i2       m3_ca1
  564. 16435  * |------------+---------+-----------+---------------|
  565. 16436  * |DL_INIT_REPL| port nr | last port | ethernet addr |
  566. 16437  * |------------|---------|-----------|---------------|
  567. 16438  *
  568. 16439  * Created:     before Dec 28, 1992 by Philip Homburg <philip@cs.vu.nl>
  569. 16440  *
  570. 16441  *              Modified to become a generic dp8390 driver.
  571. 16442  *                      March 10, 1994, Philip Homburg
  572. 16443  */
  573. 16444
  574. 16445 #include "kernel.h"
  575. 16446 #include <stdlib.h>
  576. 16447 #include <minix/com.h>
  577. 16448 #include <net/hton.h>
  578. 16449 #include <net/gen/ether.h>
  579. 16450 #include <net/gen/eth_io.h>
  580. 16451 #include "assert.h"
  581. 16452 INIT_ASSERT
  582. 16453 #include "protect.h"
  583. 16454 #include "dp8390.h"
  584. 16455 #include "proc.h"
  585. 16456
  586. 16457 #if ENABLE_NETWORKING
  587. 16458
  588. 16459 #if !__minix_vmd
  589. 16460 #define printW()        (void) 0
  590. 16461 #define debug           0
  591. 16462 #endif
  592. 16463
  593. 16464 #define DE_PORT_NR      2
  594. 16465
  595. 16466 static dpeth_t de_table[DE_PORT_NR];
  596. 16467 static int int_pending[NR_IRQ_VECTORS];
  597. 16468 static int dpeth_tasknr= ANY;
  598. 16469 static u16_t eth_ign_proto;
  599. 16470
  600. 16471 /* Configuration */
  601. 16472 typedef struct dp_conf
  602. 16473 {
  603. 16474         port_t dpc_port;
  604. 16475         int dpc_irq;
  605. 16476         phys_bytes dpc_mem;
  606. 16477         char *dpc_envvar;
  607. 16478         segm_t dpc_prot_sel;
  608. 16479 } dp_conf_t;
  609. 16480
  610. 16481 dp_conf_t dp_conf[]=    /* Card addresses */
  611. 16482 {
  612. 16483         /* I/O port, IRQ,  Buffer address,  Env. var,   Buf selector. */
  613. 16484         {  0x280,     3,    0xD0000,        "DPETH0",  DP_ETH0_SELECTOR },
  614. 16485         {  0x300,     5,    0xCC000,        "DPETH1",  DP_ETH1_SELECTOR },
  615. 16486 };
  616. 16487
  617. 16488 /* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
  618. 16489  * the error: "array size is negative".
  619. 16490  */
  620. 16491 extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
  621. 16492
  622. 16493
  623. 16494 _PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
  624. 16495                                                         int vectored)   );
  625. 16496 _PROTOTYPE( static void do_vread, (message *mp, int vectored)           );
  626. 16497 _PROTOTYPE( static void do_init, (message *mp)                          );
  627. 16498 _PROTOTYPE( static void do_int, (dpeth_t *dep)                          );
  628. 16499 _PROTOTYPE( static void do_getstat, (message *mp)                       );
  629. 16500 _PROTOTYPE( static void do_stop, (message *mp)                          );
  630. 16501 _PROTOTYPE( static void dp_init, (dpeth_t *dep)                         );
  631. 16502 _PROTOTYPE( static void dp_confaddr, (dpeth_t *dep)                     );
  632. 16503 _PROTOTYPE( static void dp_reinit, (dpeth_t *dep)                       );
  633. 16504 _PROTOTYPE( static void dp_reset, (dpeth_t *dep)                        );
  634. 16505 _PROTOTYPE( static void dp_check_ints, (dpeth_t *dep)                   );
  635. 16506 _PROTOTYPE( static void dp_recv, (dpeth_t *dep)                         );
  636. 16507 _PROTOTYPE( static void dp_send, (dpeth_t *dep)                         );
  637. 16508 _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
  638. 16509                                 size_t offset, size_t size, void *dst)  );
  639. 16510 _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
  640. 16511                                 size_t offset, size_t size, void *dst)  );
  641. 16512 _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
  642. 16513                                 size_t offset, size_t size, void *dst)  );
  643. 16514 _PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
  644. 16515                                                         int length)     );
  645. 16516 _PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp, 
  646. 16517                 vir_bytes offset, int nic_addr, vir_bytes count)        );
  647. 16518 _PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
  648. 16519                                 iovec_dat_t *iovp, vir_bytes offset,
  649. 16520                                 int nic_addr, vir_bytes count)          );
  650. 16521 _PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
  651. 16522                                 iovec_dat_t *iovp, vir_bytes offset,
  652. 16523                                 int nic_addr, vir_bytes count)          );
  653. 16524 _PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr, 
  654. 16525                 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  655. 16526 _PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr, 
  656. 16527                 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  657. 16528 _PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr, 
  658. 16529                 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  659. 16530 _PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp)              );
  660. 16531 _PROTOTYPE( static int dp_handler, (int irq)                            );
  661. 16532 _PROTOTYPE( static void conf_hw, (dpeth_t *dep)                         );
  662. 16533 _PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp)     );
  663. 16534 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp)             );
  664. 16535 _PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block)   );
  665. 16536 _PROTOTYPE( static void mess_reply, (message *req, message *reply)      );
  666. 16537 _PROTOTYPE( static void get_userdata, (int user_proc,
  667. 16538                 vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
  668. 16539 _PROTOTYPE( static void put_userdata, (int user_proc,
  669. 16540                 vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
  670. 16541
  671. 16542 /*===========================================================================*
  672. 16543  *                              dpeth_task                                   *
  673. 16544  *===========================================================================*/
  674. 16545 void dp8390_task()
  675. 16546 {
  676. 16547         message m;
  677. 16548         int i, irq, r;
  678. 16549         dpeth_t *dep;
  679. 16550         long v;
  680. 16551
  681. 16552         dpeth_tasknr= proc_number(proc_ptr);
  682. 16553
  683. 16554         v= 0xFFFF;
  684. 16555         (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
  685. 16556         eth_ign_proto= htons((u16_t) v);
  686. 16557
  687. 16558         while (TRUE)
  688. 16559         {
  689. 16560                 if ((r= receive(ANY, &m)) != OK)
  690. 16561                         panic("dp8390: receive failed", r);
  691. 16562
  692. 16563                 switch (m.m_type)
  693. 16564                 {
  694. 16565                 case DL_WRITE:  do_vwrite(&m, FALSE, FALSE);    break;
  695. 16566                 case DL_WRITEV: do_vwrite(&m, FALSE, TRUE);     break;
  696. 16567                 case DL_READ:   do_vread(&m, FALSE);            break;
  697. 16568                 case DL_READV:  do_vread(&m, TRUE);             break;
  698. 16569                 case DL_INIT:   do_init(&m);                    break;
  699. 16570                 case DL_GETSTAT: do_getstat(&m);                break;
  700. 16571                 case DL_STOP:   do_stop(&m);                    break;
  701. 16572                 case HARD_INT:
  702. 16573                         for (i= 0, dep= &de_table[0]; i<DE_PORT_NR; i++, dep++)
  703. 16574                         {
  704. 16575                                 if (dep->de_mode != DEM_ENABLED)
  705. 16576                                         continue;
  706. 16577                                 assert(dep->de_flags & DEF_ENABLED);
  707. 16578                                 irq= dep->de_irq;
  708. 16579                                 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
  709. 16580                                 if (int_pending[irq])
  710. 16581                                 {
  711. 16582                                         int_pending[irq]= 0;
  712. 16583                                         dp_check_ints(dep);
  713. 16584                                         do_int(dep);
  714. 16585                                 }
  715. 16586                         }
  716. 16587                         break;
  717. 16588                 default:
  718. 16589                         panic("dp8390: illegal message", m.m_type);
  719. 16590                 }
  720. 16591         }
  721. 16592 }
  722. 16595 /*===========================================================================*
  723. 16596  *                              dp_dump                                      *
  724. 16597  *===========================================================================*/
  725. 16598 void dp_dump()
  726. 16599 {
  727. 16600         dpeth_t *dep;
  728. 16601         int i, isr;
  729. 16602
  730. 16603         printf("n");
  731. 16604         for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
  732. 16605         {
  733. 16606                 if (dep->de_mode == DEM_DISABLED)
  734. 16607                         printf("dp8390 port %d is disabledn", i);
  735. 16608                 else if (dep->de_mode == DEM_SINK)
  736. 16609                         printf("dp8390 port %d is in sink moden", i);
  737. 16610
  738. 16611                 if (dep->de_mode != DEM_ENABLED)
  739. 16612                         continue;
  740. 16613
  741. 16614                 printf("dp8390 statistics of port %d:n", i);
  742. 16615
  743. 16616                 printf("recvErr    :%8ldt", dep->de_stat.ets_recvErr);
  744. 16617                 printf("sendErr    :%8ldt", dep->de_stat.ets_sendErr);
  745. 16618                 printf("OVW        :%8ldn", dep->de_stat.ets_OVW);
  746. 16619
  747. 16620                 printf("CRCerr     :%8ldt", dep->de_stat.ets_CRCerr);
  748. 16621                 printf("frameAll   :%8ldt", dep->de_stat.ets_frameAll);
  749. 16622                 printf("missedP    :%8ldn", dep->de_stat.ets_missedP);
  750. 16623
  751. 16624                 printf("packetR    :%8ldt", dep->de_stat.ets_packetR);
  752. 16625                 printf("packetT    :%8ldt", dep->de_stat.ets_packetT);
  753. 16626                 printf("transDef   :%8ldn", dep->de_stat.ets_transDef);
  754. 16627
  755. 16628                 printf("collision  :%8ldt", dep->de_stat.ets_collision);
  756. 16629                 printf("transAb    :%8ldt", dep->de_stat.ets_transAb);
  757. 16630                 printf("carrSense  :%8ldn", dep->de_stat.ets_carrSense);
  758. 16631
  759. 16632                 printf("fifoUnder  :%8ldt", dep->de_stat.ets_fifoUnder);
  760. 16633                 printf("fifoOver   :%8ldt", dep->de_stat.ets_fifoOver);
  761. 16634                 printf("CDheartbeat:%8ldn", dep->de_stat.ets_CDheartbeat);
  762. 16635
  763. 16636                 printf("OWC        :%8ldt", dep->de_stat.ets_OWC);
  764. 16637
  765. 16638                 isr= inb_reg0(dep, DP_ISR);
  766. 16639                 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%xn", isr,
  767. 16640                                         inb_reg0(dep, DP_ISR), dep->de_flags);
  768. 16641         }
  769. 16642 }
  770. 16645 /*===========================================================================*
  771. 16646  *                              dp8390_stop                                  *
  772. 16647  *===========================================================================*/
  773. 16648 void dp8390_stop()
  774. 16649 {
  775. 16650         message mess;
  776. 16651         int i;
  777. 16652
  778. 16653         for (i= 0; i<DE_PORT_NR; i++)
  779. 16654         {
  780. 16655                 if (de_table[i].de_mode != DEM_ENABLED)
  781. 16656                         continue;
  782. 16657                 mess.m_type= DL_STOP;
  783. 16658                 mess.DL_PORT= i;
  784. 16659                 do_stop(&mess);
  785. 16660         }
  786. 16661 }
  787. 16664 /*===========================================================================*
  788. 16665  *                              do_vwrite                                    *
  789. 16666  *===========================================================================*/
  790. 16667 static void do_vwrite(mp, from_int, vectored)
  791. 16668 message *mp;
  792. 16669 int from_int;
  793. 16670 int vectored;
  794. 16671 {
  795. 16672         int port, count, size;
  796. 16673         int sendq_head;
  797. 16674         dpeth_t *dep;
  798. 16675
  799. 16676         port = mp->DL_PORT;
  800. 16677         count = mp->DL_COUNT;
  801. 16678         if (port < 0 || port >= DE_PORT_NR)
  802. 16679                 panic("dp8390: illegal port", port);
  803. 16680         dep= &de_table[port];
  804. 16681         dep->de_client= mp->DL_PROC;
  805. 16682
  806. 16683         if (dep->de_mode == DEM_SINK)
  807. 16684         {
  808. 16685                 assert(!from_int);
  809. 16686                 dep->de_flags |= DEF_PACK_SEND;
  810. 16687                 reply(dep, OK, FALSE);
  811. 16688                 return;
  812. 16689         }
  813. 16690         assert(dep->de_mode == DEM_ENABLED);
  814. 16691         assert(dep->de_flags & DEF_ENABLED);
  815. 16692         if (dep->de_flags & DEF_SEND_AVAIL)
  816. 16693                 panic("dp8390: send already in progress", NO_NUM);
  817. 16694
  818. 16695         sendq_head= dep->de_sendq_head;
  819. 16696         if (dep->de_sendq[sendq_head].sq_filled)
  820. 16697         {
  821. 16698                 if (from_int)
  822. 16699                         panic("dp8390: should not be sendingn", NO_NUM);
  823. 16700                 dep->de_sendmsg= *mp;
  824. 16701                 dep->de_flags |= DEF_SEND_AVAIL;
  825. 16702                 reply(dep, OK, FALSE);
  826. 16703                 return;
  827. 16704         }
  828. 16705         assert(!(dep->de_flags & DEF_PACK_SEND));
  829. 16706
  830. 16707         if (vectored)
  831. 16708         {
  832. 16709                 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  833. 16710                         (count > IOVEC_NR ? IOVEC_NR : count) *
  834. 16711                         sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
  835. 16712                 dep->de_write_iovec.iod_iovec_s = count;
  836. 16713                 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
  837. 16714                 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
  838. 16715
  839. 16716                 dep->de_tmp_iovec = dep->de_write_iovec;
  840. 16717                 size = calc_iovec_size(&dep->de_tmp_iovec);
  841. 16718         }
  842. 16719         else
  843. 16720         {  
  844. 16721                 dep->de_write_iovec.iod_iovec[0].iov_addr =
  845. 16722                         (vir_bytes) mp->DL_ADDR;
  846. 16723                 dep->de_write_iovec.iod_iovec[0].iov_size =
  847. 16724                         mp->DL_COUNT;
  848. 16725                 dep->de_write_iovec.iod_iovec_s = 1;
  849. 16726                 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
  850. 16727                 dep->de_write_iovec.iod_iovec_addr = 0;
  851. 16728                 size= mp->DL_COUNT;
  852. 16729         }
  853. 16730         if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
  854. 16731         {
  855. 16732                 panic("dp8390: invalid packet size", size);
  856. 16733         }
  857. 16734         (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
  858. 16735                 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
  859. 16736                 size);
  860. 16737         dep->de_sendq[sendq_head].sq_filled= TRUE;
  861. 16738         if (dep->de_sendq_tail == sendq_head)
  862. 16739         {
  863. 16740                 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
  864. 16741                 outb_reg0(dep, DP_TBCR1, size >> 8);
  865. 16742                 outb_reg0(dep, DP_TBCR0, size & 0xff);
  866. 16743                 outb_reg0(dep, DP_CR, CR_TXP);  /* there it goes.. */
  867. 16744         }
  868. 16745         else
  869. 16746                 dep->de_sendq[sendq_head].sq_size= size;
  870. 16747         
  871. 16748         if (++sendq_head == dep->de_sendq_nr)
  872. 16749                 sendq_head= 0;
  873. 16750         assert(sendq_head < SENDQ_NR);
  874. 16751         dep->de_sendq_head= sendq_head;
  875. 16752
  876. 16753         dep->de_flags |= DEF_PACK_SEND;
  877. 16754
  878. 16755         /* If the interrupt handler called, don't send a reply. The reply
  879. 16756          * will be sent after all interrupts are handled. 
  880. 16757          */
  881. 16758         if (from_int)
  882. 16759                 return;
  883. 16760         reply(dep, OK, FALSE);
  884. 16761
  885. 16762         assert(dep->de_mode == DEM_ENABLED);
  886. 16763         assert(dep->de_flags & DEF_ENABLED);
  887. 16764 }
  888. 16767 /*===========================================================================*
  889. 16768  *                              do_vread                                     *
  890. 16769  *===========================================================================*/
  891. 16770 static void do_vread(mp, vectored)
  892. 16771 message *mp;
  893. 16772 int vectored;
  894. 16773 {
  895. 16774         int port, count;
  896. 16775         int size;
  897. 16776         dpeth_t *dep;
  898. 16777
  899. 16778         port = mp->DL_PORT;
  900. 16779         count = mp->DL_COUNT;
  901. 16780         if (port < 0 || port >= DE_PORT_NR)
  902. 16781                 panic("dp8390: illegal port", port);
  903. 16782         dep= &de_table[port];
  904. 16783         dep->de_client= mp->DL_PROC;
  905. 16784         if (dep->de_mode == DEM_SINK)
  906. 16785         {
  907. 16786                 reply(dep, OK, FALSE);
  908. 16787                 return;
  909. 16788         }
  910. 16789         assert(dep->de_mode == DEM_ENABLED);
  911. 16790         assert(dep->de_flags & DEF_ENABLED);
  912. 16791
  913. 16792         if(dep->de_flags & DEF_READING)
  914. 16793                 panic("dp8390: read already in progress", NO_NUM);
  915. 16794
  916. 16795         if (vectored)
  917. 16796         {
  918. 16797                 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  919. 16798                         (count > IOVEC_NR ? IOVEC_NR : count) *
  920. 16799                         sizeof(iovec_t), dep->de_read_iovec.iod_iovec);
  921. 16800                 dep->de_read_iovec.iod_iovec_s = count;
  922. 16801                 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
  923. 16802                 dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
  924. 16803
  925. 16804                 dep->de_tmp_iovec = dep->de_read_iovec;
  926. 16805                 size= calc_iovec_size(&dep->de_tmp_iovec);
  927. 16806         }
  928. 16807         else
  929. 16808         {
  930. 16809                 dep->de_read_iovec.iod_iovec[0].iov_addr =
  931. 16810                         (vir_bytes) mp->DL_ADDR;
  932. 16811                 dep->de_read_iovec.iod_iovec[0].iov_size =
  933. 16812                         mp->DL_COUNT;
  934. 16813                 dep->de_read_iovec.iod_iovec_s = 1;
  935. 16814                 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
  936. 16815                 dep->de_read_iovec.iod_iovec_addr = 0;
  937. 16816                 size= count;
  938. 16817         }
  939. 16818         if (size < ETH_MAX_PACK_SIZE)
  940. 16819                 panic("dp8390: wrong packet size", size);
  941. 16820         dep->de_flags |= DEF_READING;
  942. 16821
  943. 16822         dp_recv(dep);
  944. 16823
  945. 16824         if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
  946. 16825                 (DEF_READING|DEF_STOPPED))
  947. 16826         {
  948. 16827                 /* The chip is stopped, and all arrived packets are 
  949. 16828                  * delivered.
  950. 16829                  */
  951. 16830                 dp_reset(dep);
  952. 16831         }
  953. 16832         reply(dep, OK, FALSE);
  954. 16833 }
  955. 16836 /*===========================================================================*
  956. 16837  *                              do_init                                      *
  957. 16838  *===========================================================================*/
  958. 16839 static void do_init(mp)
  959. 16840 message *mp;
  960. 16841 {
  961. 16842         int port;
  962. 16843         dpeth_t *dep;
  963. 16844         message reply_mess;
  964. 16845
  965. 16846         port = mp->DL_PORT;
  966. 16847         if (port < 0 || port >= DE_PORT_NR)
  967. 16848         {
  968. 16849                 reply_mess.m_type= DL_INIT_REPLY;
  969. 16850                 reply_mess.m3_i1= ENXIO;
  970. 16851                 mess_reply(mp, &reply_mess);
  971. 16852                 return;
  972. 16853         }
  973. 16854         dep= &de_table[port];
  974. 16855         if (dep->de_mode == DEM_DISABLED)
  975. 16856         {
  976. 16857                 /* This is the default, try to (re)locate the device. */
  977. 16858                 conf_hw(dep);
  978. 16859                 if (dep->de_mode == DEM_DISABLED)
  979. 16860                 {
  980. 16861                         /* Probe failed, or the device is configured off. */
  981. 16862                         reply_mess.m_type= DL_INIT_REPLY;
  982. 16863                         reply_mess.m3_i1= ENXIO;
  983. 16864                         mess_reply(mp, &reply_mess);
  984. 16865                         return;
  985. 16866                 }
  986. 16867                 if (dep->de_mode == DEM_ENABLED)
  987. 16868                         dp_init(dep);
  988. 16869         }
  989. 16870
  990. 16871         if (dep->de_mode == DEM_SINK)
  991. 16872         {
  992. 16873                 dep->de_address.ea_addr[0] = 
  993. 16874                         dep->de_address.ea_addr[1] = 
  994. 16875                         dep->de_address.ea_addr[2] = 
  995. 16876                         dep->de_address.ea_addr[3] = 
  996. 16877                         dep->de_address.ea_addr[4] = 
  997. 16878                         dep->de_address.ea_addr[5] = 0;
  998. 16879                 dp_confaddr(dep);
  999. 16880                 reply_mess.m_type = DL_INIT_REPLY;
  1000. 16881                 reply_mess.m3_i1 = mp->DL_PORT;
  1001. 16882                 reply_mess.m3_i2 = DE_PORT_NR;
  1002. 16883                 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  1003. 16884                 mess_reply(mp, &reply_mess);
  1004. 16885                 return;
  1005. 16886         }
  1006. 16887         assert(dep->de_mode == DEM_ENABLED);
  1007. 16888         assert(dep->de_flags & DEF_ENABLED);
  1008. 16889
  1009. 16890         dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
  1010. 16891
  1011. 16892         if (mp->DL_MODE & DL_PROMISC_REQ)
  1012. 16893                 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
  1013. 16894         if (mp->DL_MODE & DL_MULTI_REQ)
  1014. 16895                 dep->de_flags |= DEF_MULTI;
  1015. 16896         if (mp->DL_MODE & DL_BROAD_REQ)
  1016. 16897                 dep->de_flags |= DEF_BROAD;
  1017. 16898
  1018. 16899         dep->de_client = mp->m_source;
  1019. 16900         dp_reinit(dep);
  1020. 16901
  1021. 16902         reply_mess.m_type = DL_INIT_REPLY;
  1022. 16903         reply_mess.m3_i1 = mp->DL_PORT;
  1023. 16904         reply_mess.m3_i2 = DE_PORT_NR;
  1024. 16905         *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  1025. 16906
  1026. 16907         mess_reply(mp, &reply_mess);
  1027. 16908 }
  1028. 16910 /*===========================================================================*
  1029. 16911  *                              do_int                                       *
  1030. 16912  *===========================================================================*/
  1031. 16913 static void do_int(dep)
  1032. 16914 dpeth_t *dep;
  1033. 16915 {
  1034. 16916         if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
  1035. 16917                 reply(dep, OK, TRUE);
  1036. 16918 }
  1037. 16921 /*===========================================================================*
  1038. 16922  *                              do_getstat                                   *
  1039. 16923  *===========================================================================*/
  1040. 16924 static void do_getstat(mp)
  1041. 16925 message *mp;
  1042. 16926 {
  1043. 16927         int port;
  1044. 16928         dpeth_t *dep;
  1045. 16929
  1046. 16930         port = mp->DL_PORT;
  1047. 16931         if (port < 0 || port >= DE_PORT_NR)
  1048. 16932                 panic("dp8390: illegal port", port);
  1049. 16933         dep= &de_table[port];
  1050. 16934         dep->de_client= mp->DL_PROC;
  1051. 16935         if (dep->de_mode == DEM_SINK)
  1052. 16936         {
  1053. 16937                 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  1054. 16938                         (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
  1055. 16939                 reply(dep, OK, FALSE);
  1056. 16940                 return;
  1057. 16941         }
  1058. 16942         assert(dep->de_mode == DEM_ENABLED);
  1059. 16943         assert(dep->de_flags & DEF_ENABLED);
  1060. 16944
  1061. 16945         dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
  1062. 16946         dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
  1063. 16947         dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
  1064. 16948
  1065. 16949         put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  1066. 16950                 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
  1067. 16951         reply(dep, OK, FALSE);
  1068. 16952 }
  1069. 16955 /*===========================================================================*
  1070. 16956  *                              do_stop                                      *
  1071. 16957  *===========================================================================*/
  1072. 16958 static void do_stop(mp)
  1073. 16959 message *mp;
  1074. 16960 {
  1075. 16961         int port;
  1076. 16962         dpeth_t *dep;
  1077. 16963
  1078. 16964         port = mp->DL_PORT;
  1079. 16965
  1080. 16966         if (port < 0 || port >= DE_PORT_NR)
  1081. 16967                 panic("dp8390: illegal port", port);
  1082. 16968         dep= &de_table[port];
  1083. 16969         if (dep->de_mode == DEM_SINK)
  1084. 16970                 return;
  1085. 16971         assert(dep->de_mode == DEM_ENABLED);
  1086. 16972
  1087. 16973         if (!(dep->de_flags & DEF_ENABLED))
  1088. 16974                 return;
  1089. 16975
  1090. 16976         outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
  1091. 16977         (dep->de_stopf)(dep);
  1092. 16978
  1093. 16979         dep->de_flags= DEF_EMPTY;
  1094. 16980 }
  1095. 16983 /*===========================================================================*
  1096. 16984  *                              dp_init                                      *
  1097. 16985  *===========================================================================*/
  1098. 16986 static void dp_init(dep)
  1099. 16987 dpeth_t *dep;
  1100. 16988 {
  1101. 16989         int dp_rcr_reg;
  1102. 16990         int i;
  1103. 16991
  1104. 16992         /* General initialization */
  1105. 16993         dep->de_flags = DEF_EMPTY;
  1106. 16994         (*dep->de_initf)(dep);
  1107. 16995
  1108. 16996         dp_confaddr(dep);
  1109. 16997
  1110. 16998         /* Initialization of the dp8390 */
  1111. 16999         outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
  1112. 17000         outb_reg0(dep, DP_IMR, 0);
  1113. 17001         outb_reg0(dep, DP_PSTART, dep->de_startpage);
  1114. 17002         outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
  1115. 17003         outb_reg0(dep, DP_BNRY, dep->de_startpage);
  1116. 17004         outb_reg0(dep, DP_RCR, RCR_MON);
  1117. 17005         outb_reg0(dep, DP_TCR, TCR_NORMAL);
  1118. 17006         if (dep->de_16bit)
  1119. 17007                 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
  1120. 17008         else
  1121. 17009                 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
  1122. 17010         outb_reg0(dep, DP_RBCR0, 0);
  1123. 17011         outb_reg0(dep, DP_RBCR1, 0);
  1124. 17012         outb_reg0(dep, DP_ISR, 0xFF);
  1125. 17013         outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT);
  1126. 17014
  1127. 17015         outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
  1128. 17016         outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
  1129. 17017         outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
  1130. 17018         outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
  1131. 17019         outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
  1132. 17020         outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
  1133. 17021
  1134. 17022         outb_reg1(dep, DP_MAR0, 0xff);
  1135. 17023         outb_reg1(dep, DP_MAR1, 0xff);
  1136. 17024         outb_reg1(dep, DP_MAR2, 0xff);
  1137. 17025         outb_reg1(dep, DP_MAR3, 0xff);
  1138. 17026         outb_reg1(dep, DP_MAR4, 0xff);
  1139. 17027         outb_reg1(dep, DP_MAR5, 0xff);
  1140. 17028         outb_reg1(dep, DP_MAR6, 0xff);
  1141. 17029         outb_reg1(dep, DP_MAR7, 0xff);
  1142. 17030
  1143. 17031         outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
  1144. 17032         outb_reg1(dep, DP_CR, CR_PS_P0 | CR_DM_ABORT);
  1145. 17033
  1146. 17034         dp_rcr_reg = 0;
  1147. 17035         if (dep->de_flags & DEF_PROMISC)
  1148. 17036                 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
  1149. 17037         if (dep->de_flags & DEF_BROAD)
  1150. 17038                 dp_rcr_reg |= RCR_AB;
  1151. 17039         if (dep->de_flags & DEF_MULTI)
  1152. 17040                 dp_rcr_reg |= RCR_AM;
  1153. 17041         outb_reg0(dep, DP_RCR, dp_rcr_reg);
  1154. 17042         inb_reg0(dep, DP_CNTR0);                /* reset counters by reading */
  1155. 17043         inb_reg0(dep, DP_CNTR1);
  1156. 17044         inb_reg0(dep, DP_CNTR2);
  1157. 17045
  1158. 17046         outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
  1159. 17047                 IMR_OVWE | IMR_CNTE);
  1160. 17048         outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT);
  1161. 17049
  1162. 17050         /* Finish the initialization. */
  1163. 17051         dep->de_flags |= DEF_ENABLED;
  1164. 17052         for (i= 0; i<dep->de_sendq_nr; i++)
  1165. 17053                 dep->de_sendq[i].sq_filled= 0;
  1166. 17054         dep->de_sendq_head= 0;
  1167. 17055         dep->de_sendq_tail= 0;
  1168. 17056         if (!dep->de_prog_IO)
  1169. 17057         {
  1170. 17058                 dep->de_user2nicf= dp_user2nic;
  1171. 17059                 dep->de_nic2userf= dp_nic2user;
  1172. 17060                 dep->de_getblockf= dp_getblock;
  1173. 17061         }
  1174. 17062         else if (dep->de_16bit)
  1175. 17063         {
  1176. 17064                 dep->de_user2nicf= dp_pio16_user2nic;
  1177. 17065                 dep->de_nic2userf= dp_pio16_nic2user;
  1178. 17066                 dep->de_getblockf= dp_pio16_getblock;
  1179. 17067         }
  1180. 17068         else
  1181. 17069         {
  1182. 17070                 dep->de_user2nicf= dp_pio8_user2nic;
  1183. 17071                 dep->de_nic2userf= dp_pio8_nic2user;
  1184. 17072                 dep->de_getblockf= dp_pio8_getblock;
  1185. 17073         }
  1186. 17074
  1187. 17075         /* set the interrupt handler */
  1188. 17076         put_irq_handler(dep->de_irq, dp_handler);
  1189. 17077         enable_irq(dep->de_irq);
  1190. 17078 }
  1191. 17081 /*===========================================================================*
  1192. 17082  *                              dp_confaddr                                  *
  1193. 17083  *===========================================================================*/
  1194. 17084 static void dp_confaddr(dep)
  1195. 17085 dpeth_t *dep;
  1196. 17086 {
  1197. 17087         int i;
  1198. 17088         char eakey[16];
  1199. 17089         static char eafmt[]= "x:x:x:x:x:x";
  1200. 17090         long v;
  1201. 17091
  1202. 17092         /* User defined ethernet address? */
  1203. 17093         strcpy(eakey, dp_conf[dep-de_table].dpc_envvar);
  1204. 17094         strcat(eakey, "_EA");
  1205. 17095
  1206. 17096         for (i= 0; i < 6; i++)
  1207. 17097         {
  1208. 17098                 v= dep->de_address.ea_addr[i];
  1209. 17099                 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
  1210. 17100                         break;
  1211. 17101                 dep->de_address.ea_addr[i]= v;
  1212. 17102         }
  1213. 17103
  1214. 17104         if (i != 0 && i != 6)
  1215. 17105         {
  1216. 17106                 /* It's all or nothing; force a panic. */
  1217. 17107                 (void) env_parse(eakey, "?", 0, &v, 0L, 0L);
  1218. 17108         }
  1219. 17109 }
  1220. 17112 /*===========================================================================*
  1221. 17113  *                              dp_reinit                                    *
  1222. 17114  *===========================================================================*/
  1223. 17115 static void dp_reinit(dep)
  1224. 17116 dpeth_t *dep;
  1225. 17117 {
  1226. 17118         int dp_rcr_reg;
  1227. 17119
  1228. 17120         outb_reg0(dep, DP_CR, CR_PS_P0);
  1229. 17121
  1230. 17122         dp_rcr_reg = 0;
  1231. 17123         if (dep->de_flags & DEF_PROMISC)
  1232. 17124                 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
  1233. 17125         if (dep->de_flags & DEF_BROAD)
  1234. 17126                 dp_rcr_reg |= RCR_AB;
  1235. 17127         if (dep->de_flags & DEF_MULTI)
  1236. 17128                 dp_rcr_reg |= RCR_AM;
  1237. 17129         outb_reg0(dep, DP_RCR, dp_rcr_reg);
  1238. 17130 }
  1239. 17133 /*===========================================================================*
  1240. 17134  *                              dp_reset                                     *
  1241. 17135  *===========================================================================*/
  1242. 17136 static void dp_reset(dep)
  1243. 17137 dpeth_t *dep;
  1244. 17138 {
  1245. 17139         int i;
  1246. 17140
  1247. 17141         /* Stop chip */
  1248. 17142         outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
  1249. 17143         outb_reg0(dep, DP_RBCR0, 0);
  1250. 17144         outb_reg0(dep, DP_RBCR1, 0);
  1251. 17145         for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
  1252. 17146                 ; /* Do nothing */
  1253. 17147         outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
  1254. 17148         outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
  1255. 17149         outb_reg0(dep, DP_TCR, TCR_NORMAL|TCR_OFST);
  1256. 17150
  1257. 17151         /* Acknowledge the ISR_RDC (remote dma) interrupt. */
  1258. 17152         for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
  1259. 17153                 ; /* Do nothing */
  1260. 17154         outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
  1261. 17155
  1262. 17156         /* Reset the transmit ring. If we were transmitting a packet, we
  1263. 17157          * pretend that the packet is processed. Higher layers will
  1264. 17158          * retransmit if the packet wasn't actually sent.
  1265. 17159          */
  1266. 17160         dep->de_sendq_head= dep->de_sendq_tail= 0;
  1267. 17161         for (i= 0; i<dep->de_sendq_nr; i++)
  1268. 17162                 dep->de_sendq[i].sq_filled= 0;
  1269. 17163         dp_send(dep);
  1270. 17164         dep->de_flags &= ~DEF_STOPPED;
  1271. 17165 }
  1272. 17168 /*===========================================================================*
  1273. 17169  *                              dp_check_ints                                *
  1274. 17170  *===========================================================================*/
  1275. 17171 static void dp_check_ints(dep)
  1276. 17172 dpeth_t *dep;
  1277. 17173 {
  1278. 17174         int isr, tsr;
  1279. 17175         int size, sendq_tail;
  1280. 17176
  1281. 17177         if (!(dep->de_flags & DEF_ENABLED))
  1282. 17178                 panic("dp8390: got premature interrupt", NO_NUM);
  1283. 17179
  1284. 17180         for(;;)
  1285. 17181         {
  1286. 17182                 isr = inb_reg0(dep, DP_ISR);
  1287. 17183                 if (!isr)
  1288. 17184                         break;
  1289. 17185                 outb_reg0(dep, DP_ISR, isr);
  1290. 17186                 if (isr & (ISR_PTX|ISR_TXE))
  1291. 17187                 {
  1292. 17188                         if (isr & ISR_TXE)
  1293. 17189                         {
  1294. 17190 #if DEBUG
  1295. 17191  { printf("dp8390: got send Errorn"); }
  1296. 17192 #endif
  1297. 17193                                 dep->de_stat.ets_sendErr++;
  1298. 17194                         }
  1299. 17195                         else
  1300. 17196                         {
  1301. 17197                                 tsr = inb_reg0(dep, DP_TSR);
  1302. 17198
  1303. 17199                                 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
  1304. 17200                                 if (tsr & TSR_DFR) dep->de_stat.ets_transDef++;
  1305. 17201                                 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
  1306. 17202                                 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
  1307. 17203                                 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
  1308. 17204                                 if (tsr & TSR_FU
  1309. 17205                                         && ++dep->de_stat.ets_fifoUnder <= 10)
  1310. 17206                                 {
  1311. 17207                                         printf("dp8390: fifo underrunn");
  1312. 17208                                 }
  1313. 17209                                 if (tsr & TSR_CDH
  1314. 17210                                         && ++dep->de_stat.ets_CDheartbeat <= 10)
  1315. 17211                                 {
  1316. 17212                                         printf(
  1317. 17213                                         "dp8390: CD heart beat failuren");
  1318. 17214                                 }
  1319. 17215                                 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
  1320. 17216                         }
  1321. 17217                         sendq_tail= dep->de_sendq_tail;
  1322. 17218
  1323. 17219                         if (!(dep->de_sendq[sendq_tail].sq_filled))
  1324. 17220                         {
  1325. 17221                                 /* Software bug? */
  1326. 17222                                 assert(!debug);
  1327. 17223
  1328. 17224                                 /* Or hardware bug? */
  1329. 17225                                 printf(
  1330. 17226                         "dp8390: transmit interrupt, but not sendingn");
  1331. 17227                                 continue;
  1332. 17228                         }
  1333. 17229                         dep->de_sendq[sendq_tail].sq_filled= 0;
  1334. 17230                         if (++sendq_tail == dep->de_sendq_nr)
  1335. 17231                                 sendq_tail= 0;
  1336. 17232                         dep->de_sendq_tail= sendq_tail;
  1337. 17233                         if (dep->de_sendq[sendq_tail].sq_filled)
  1338. 17234                         {
  1339. 17235                                 size= dep->de_sendq[sendq_tail].sq_size;
  1340. 17236                                 outb_reg0(dep, DP_TPSR,
  1341. 17237                                         dep->de_sendq[sendq_tail].sq_sendpage);
  1342. 17238                                 outb_reg0(dep, DP_TBCR1, size >> 8);
  1343. 17239                                 outb_reg0(dep, DP_TBCR0, size & 0xff);
  1344. 17240                                 outb_reg0(dep, DP_CR, CR_TXP);  /* there is goes.. */
  1345. 17241                         }
  1346. 17242                         if (dep->de_flags & DEF_SEND_AVAIL)
  1347. 17243                                 dp_send(dep);
  1348. 17244                 }
  1349. 17245
  1350. 17246                 if (isr & ISR_PRX)
  1351. 17247                         dp_recv(dep);
  1352. 17248                 
  1353. 17249                 if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
  1354. 17250                 if (isr & ISR_CNT)
  1355. 17251                 {
  1356. 17252                         dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
  1357. 17253                         dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
  1358. 17254                         dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
  1359. 17255                 }
  1360. 17256                 if (isr & ISR_OVW)
  1361. 17257                 {
  1362. 17258 #if DEBUG
  1363. 17259  { printW(); printf("dp8390: got overwrite warningn"); }
  1364. 17260 #endif
  1365. 17261                 }
  1366. 17262                 if (isr & ISR_RDC)
  1367. 17263                 {
  1368. 17264                         /* Nothing to do */
  1369. 17265                 }
  1370. 17266                 if (isr & ISR_RST)
  1371. 17267                 {
  1372. 17268                         /* this means we got an interrupt but the ethernet 
  1373. 17269                          * chip is shutdown. We set the flag DEF_STOPPED,
  1374. 17270                          * and continue processing arrived packets. When the
  1375. 17271                          * receive buffer is empty, we reset the dp8390.
  1376. 17272                          */
  1377. 17273 #if DEBUG
  1378. 17274  { printW(); printf("dp8390: NIC stoppedn"); }
  1379. 17275 #endif
  1380. 17276                         dep->de_flags |= DEF_STOPPED;
  1381. 17277                         break;
  1382. 17278                 }
  1383. 17279         }
  1384. 17280         if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) == 
  1385. 17281                                                 (DEF_READING|DEF_STOPPED))
  1386. 17282         {
  1387. 17283                 /* The chip is stopped, and all arrived packets are 
  1388. 17284                  * delivered.
  1389. 17285                  */
  1390. 17286                 dp_reset(dep);
  1391. 17287         }
  1392. 17288 }
  1393. 17291 /*===========================================================================*
  1394. 17292  *                              dp_recv                                      *
  1395. 17293  *===========================================================================*/
  1396. 17294 static void dp_recv(dep)
  1397. 17295 dpeth_t *dep;
  1398. 17296 {
  1399. 17297         dp_rcvhdr_t header;
  1400. 17298         unsigned pageno, curr, next;
  1401. 17299         vir_bytes length;
  1402. 17300         int packet_processed, r;
  1403. 17301         u16_t eth_type;
  1404. 17302
  1405. 17303         packet_processed = FALSE;
  1406. 17304         pageno = inb_reg0(dep, DP_BNRY) + 1;
  1407. 17305         if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
  1408. 17306
  1409. 17307         do
  1410. 17308         {
  1411. 17309                 outb_reg0(dep, DP_CR, CR_PS_P1);
  1412. 17310                 curr = inb_reg1(dep, DP_CURR);
  1413. 17311                 outb_reg0(dep, DP_CR, CR_PS_P0);
  1414. 17312
  1415. 17313                 if (curr == pageno) break;
  1416. 17314
  1417. 17315                 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
  1418. 17316                         &header);
  1419. 17317                 (dep->de_getblockf)(dep, pageno, sizeof(header) +
  1420. 17318                         2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
  1421. 17319
  1422. 17320                 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
  1423. 17321                         sizeof(dp_rcvhdr_t);
  1424. 17322                 next = header.dr_next;
  1425. 17323                 if (length < 60 || length > 1514)
  1426. 17324                 {
  1427. 17325                         printf(
  1428. 17326                         "dp8390: packet with strange length arrived: %dn",
  1429. 17327                                 length);
  1430. 17328                         next= curr;
  1431. 17329                 }
  1432. 17330                 else if (next < dep->de_startpage || next >= dep->de_stoppage)
  1433. 17331                 {
  1434. 17332                         printf("dp8390: strange next pagen");
  1435. 17333                         next= curr;
  1436. 17334                 }
  1437. 17335                 else if (eth_type == eth_ign_proto)
  1438. 17336                 {
  1439. 17337                         /* hack: ignore packets of a given protocol, useful
  1440. 17338                          * if you share a net with 80 computers sending
  1441. 17339                          * Amoeba FLIP broadcasts.  (Protocol 0x8146.)
  1442. 17340                          */
  1443. 17341                         static int first= 1;
  1444. 17342                         if (first)
  1445. 17343                         {
  1446. 17344                                 first= 0;
  1447. 17345                                 printW();
  1448. 17346                                 printf("dropping proto %04x packetn",
  1449. 17347                                         ntohs(eth_ign_proto));
  1450. 17348                         }
  1451. 17349                         dep->de_stat.ets_packetR++;
  1452. 17350                         next = curr;
  1453. 17351                 }
  1454. 17352                 else if (header.dr_status & RSR_FO)
  1455. 17353                 {
  1456. 17354                         /* This is very serious, so we issue a warning and
  1457. 17355                          * reset the buffers */
  1458. 17356                         printf(
  1459. 17357                         "dp8390: fifo overrun, resetting receive buffern");
  1460. 17358                         dep->de_stat.ets_fifoOver++;
  1461. 17359                         next = curr;
  1462. 17360                 }
  1463. 17361                 else if ((header.dr_status & RSR_PRX) &&
  1464. 17362                                            (dep->de_flags & DEF_ENABLED))
  1465. 17363                 {
  1466. 17364                         r = dp_pkt2user(dep, pageno, length);
  1467. 17365                         if (r != OK)
  1468. 17366                                 return;
  1469. 17367
  1470. 17368                         packet_processed = TRUE;
  1471. 17369                         dep->de_stat.ets_packetR++;
  1472. 17370                 }
  1473. 17371                 if (next == dep->de_startpage)
  1474. 17372                         outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
  1475. 17373                 else
  1476. 17374                         outb_reg0(dep, DP_BNRY, next - 1);
  1477. 17375
  1478. 17376                 pageno = next;
  1479. 17377         }
  1480. 17378         while (!packet_processed);
  1481. 17379 }
  1482. 17382 /*===========================================================================*
  1483. 17383  *                              dp_send                                      *
  1484. 17384  *===========================================================================*/
  1485. 17385 static void dp_send(dep)
  1486. 17386 dpeth_t *dep;
  1487. 17387 {
  1488. 17388         if (!(dep->de_flags & DEF_SEND_AVAIL))
  1489. 17389                 return;
  1490. 17390
  1491. 17391         dep->de_flags &= ~DEF_SEND_AVAIL;
  1492. 17392         switch(dep->de_sendmsg.m_type)
  1493. 17393         {
  1494. 17394         case DL_WRITE:  do_vwrite(&dep->de_sendmsg, TRUE, FALSE);       break;
  1495. 17395         case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE);        break;
  1496. 17396         default:
  1497. 17397                 panic("dp8390: wrong type:", dep->de_sendmsg.m_type);
  1498. 17398                 break;
  1499. 17399         }
  1500. 17400 }
  1501. 17403 /*===========================================================================*
  1502. 17404  *                              dp_getblock                                  *
  1503. 17405  *===========================================================================*/
  1504. 17406 static void dp_getblock(dep, page, offset, size, dst)
  1505. 17407 dpeth_t *dep;
  1506. 17408 int page;
  1507. 17409 size_t offset;
  1508. 17410 size_t size;
  1509. 17411 void *dst;
  1510. 17412 {
  1511. 17413         u16_t *ha;
  1512. 17414         int i;
  1513. 17415
  1514. 17416         ha = (u16_t *) dst;
  1515. 17417         offset = page * DP_PAGESIZE + offset;
  1516. 17418         assert(!(size & 1));
  1517. 17419         for (i= 0; i<size; i+=2)
  1518. 17420         {
  1519. 17421                 *ha = mem_rdw(dep->de_memsegm, offset+i);
  1520. 17422                 ha++;
  1521. 17423         }
  1522. 17424 }
  1523. 17427 /*===========================================================================*
  1524. 17428  *                              dp_pio8_getblock                             *
  1525. 17429  *===========================================================================*/
  1526. 17430 static void dp_pio8_getblock(dep, page, offset, size, dst)
  1527. 17431 dpeth_t *dep;
  1528. 17432 int page;
  1529. 17433 size_t offset;
  1530. 17434 size_t size;
  1531. 17435 void *dst;
  1532. 17436 {
  1533. 17437         u8_t *ha;
  1534. 17438         int i;
  1535. 17439
  1536. 17440         ha = (u8_t *) dst;
  1537. 17441         offset = page * DP_PAGESIZE + offset;
  1538. 17442         outb_reg0(dep, DP_RBCR0, size & 0xFF);
  1539. 17443         outb_reg0(dep, DP_RBCR1, size >> 8);
  1540. 17444         outb_reg0(dep, DP_RSAR0, offset & 0xFF);
  1541. 17445         outb_reg0(dep, DP_RSAR1, offset >> 8);
  1542. 17446         outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  1543. 17447
  1544. 17448         for (i= 0; i<size; i++)
  1545. 17449                 ha[i]= in_byte(dep->de_data_port);
  1546. 17450 }
  1547. 17453 /*===========================================================================*
  1548. 17454  *                              dp_pio16_getblock                            *
  1549. 17455  *===========================================================================*/
  1550. 17456 static void dp_pio16_getblock(dep, page, offset, size, dst)
  1551. 17457 dpeth_t *dep;
  1552. 17458 int page;
  1553. 17459 size_t offset;
  1554. 17460 size_t size;
  1555. 17461 void *dst;
  1556. 17462 {
  1557. 17463         u16_t *ha;
  1558. 17464         int i;
  1559. 17465
  1560. 17466         ha = (u16_t *) dst;
  1561. 17467         offset = page * DP_PAGESIZE + offset;
  1562. 17468         outb_reg0(dep, DP_RBCR0, size & 0xFF);
  1563. 17469         outb_reg0(dep, DP_RBCR1, size >> 8);
  1564. 17470         outb_reg0(dep, DP_RSAR0, offset & 0xFF);
  1565. 17471         outb_reg0(dep, DP_RSAR1, offset >> 8);
  1566. 17472         outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  1567. 17473
  1568. 17474         assert (!(size & 1));
  1569. 17475         size /= 2;
  1570. 17476         for (i= 0; i<size; i++)
  1571. 17477                 ha[i]= in_word(dep->de_data_port);
  1572. 17478 }
  1573. 17481 /*===========================================================================*
  1574. 17482  *                              dp_pkt2user                                  *
  1575. 17483  *===========================================================================*/
  1576. 17484 static int dp_pkt2user(dep, page, length)
  1577. 17485 dpeth_t *dep;
  1578. 17486 int page, length;
  1579. 17487 {
  1580. 17488         int last, count;
  1581. 17489
  1582. 17490         if (!(dep->de_flags & DEF_READING))
  1583. 17491                 return EGENERIC;
  1584. 17492
  1585. 17493         last = page + (length - 1) / DP_PAGESIZE;
  1586. 17494         if (last >= dep->de_stoppage)
  1587. 17495         {
  1588. 17496                 count = (dep->de_stoppage - page) * DP_PAGESIZE -
  1589. 17497                         sizeof(dp_rcvhdr_t);
  1590. 17498
  1591. 17499                 /* Save read_iovec since we need it twice. */
  1592. 17500                 dep->de_tmp_iovec = dep->de_read_iovec;
  1593. 17501                 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
  1594. 17502                         sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
  1595. 17503                 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE, 
  1596. 17504                                 &dep->de_read_iovec, count, length - count);
  1597. 17505         }
  1598. 17506         else
  1599. 17507         {
  1600. 17508                 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
  1601. 17509                         sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
  1602. 17510         }
  1603. 17511
  1604. 17512         dep->de_read_s = length;
  1605. 17513         dep->de_flags |= DEF_PACK_RECV;
  1606. 17514         dep->de_flags &= ~DEF_READING;
  1607. 17515
  1608. 17516         return OK;
  1609. 17517 }
  1610. 17520 /*===========================================================================*
  1611. 17521  *                              dp_user2nic                                  *
  1612. 17522  *===========================================================================*/
  1613. 17523 static void dp_user2nic(dep, iovp, offset, nic_addr, count)
  1614. 17524 dpeth_t *dep;
  1615. 17525 iovec_dat_t *iovp;
  1616. 17526 vir_bytes offset;
  1617. 17527 int nic_addr;
  1618. 17528 vir_bytes count;
  1619. 17529 {
  1620. 17530         phys_bytes phys_hw, phys_user;
  1621. 17531         int bytes, i;
  1622. 17532
  1623. 17533         phys_hw = dep->de_linmem + nic_addr;
  1624. 17534
  1625. 17535         i= 0;
  1626. 17536         while (count > 0)
  1627. 17537         {
  1628. 17538                 if (i >= IOVEC_NR)
  1629. 17539                 {
  1630. 17540                         dp_next_iovec(iovp);
  1631. 17541                         i= 0;
  1632. 17542                         continue;
  1633. 17543                 }
  1634. 17544                 assert(i < iovp->iod_iovec_s);
  1635. 17545                 if (offset >= iovp->iod_iovec[i].iov_size)
  1636. 17546                 {
  1637. 17547                         offset -= iovp->iod_iovec[i].iov_size;
  1638. 17548                         i++;
  1639. 17549                         continue;
  1640. 17550                 }
  1641. 17551                 bytes = iovp->iod_iovec[i].iov_size - offset;
  1642. 17552                 if (bytes > count)
  1643. 17553                         bytes = count;
  1644. 17554
  1645. 17555                 phys_user = numap(iovp->iod_proc_nr,
  1646. 17556                         iovp->iod_iovec[i].iov_addr + offset, bytes);
  1647. 17557                 if (!phys_user)
  1648. 17558                         panic("dp8390: umap failedn", NO_NUM);
  1649. 17559                 phys_copy(phys_user, phys_hw, (phys_bytes) bytes);
  1650. 17560                 count -= bytes;
  1651. 17561                 phys_hw += bytes;
  1652. 17562                 offset += bytes;
  1653. 17563         }
  1654. 17564         assert(count == 0);
  1655. 17565 }
  1656. 17568 /*===========================================================================*
  1657. 17569  *                              dp_pio8_user2nic                             *
  1658. 17570  *===========================================================================*/
  1659. 17571 static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
  1660. 17572 dpeth_t *dep;
  1661. 17573 iovec_dat_t *iovp;
  1662. 17574 vir_bytes offset;
  1663. 17575 int nic_addr;
  1664. 17576 vir_bytes count;
  1665. 17577 {
  1666. 17578         phys_bytes phys_user;
  1667. 17579         int bytes, i;
  1668. 17580
  1669. 17581         outb_reg0(dep, DP_ISR, ISR_RDC);
  1670. 17582
  1671. 17583         outb_reg0(dep, DP_RBCR0, count & 0xFF);
  1672. 17584         outb_reg0(dep, DP_RBCR1, count >> 8);
  1673. 17585         outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1674. 17586         outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1675. 17587         outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
  1676. 17588
  1677. 17589         i= 0;
  1678. 17590         while (count > 0)
  1679. 17591         {
  1680. 17592                 if (i >= IOVEC_NR)
  1681. 17593                 {
  1682. 17594                         dp_next_iovec(iovp);
  1683. 17595                         i= 0;
  1684. 17596                         continue;
  1685. 17597                 }
  1686. 17598                 assert(i < iovp->iod_iovec_s);
  1687. 17599                 if (offset >= iovp->iod_iovec[i].iov_size)
  1688. 17600                 {
  1689. 17601                         offset -= iovp->iod_iovec[i].iov_size;
  1690. 17602                         i++;
  1691. 17603                         continue;
  1692. 17604                 }
  1693. 17605                 bytes = iovp->iod_iovec[i].iov_size - offset;
  1694. 17606                 if (bytes > count)
  1695. 17607                         bytes = count;
  1696. 17608
  1697. 17609                 phys_user = numap(iovp->iod_proc_nr,
  1698. 17610                         iovp->iod_iovec[i].iov_addr + offset, bytes);
  1699. 17611                 if (!phys_user)
  1700. 17612                         panic("dp8390: umap failedn", NO_NUM);
  1701. 17613                 port_write_byte(dep->de_data_port, phys_user, bytes);
  1702. 17614                 count -= bytes;
  1703. 17615                 offset += bytes;
  1704. 17616         }
  1705. 17617         assert(count == 0);
  1706. 17618
  1707. 17619         for (i= 0; i<100; i++)
  1708. 17620         {
  1709. 17621                 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
  1710. 17622                         break;
  1711. 17623         }
  1712. 17624         if (i == 100)
  1713. 17625         {
  1714. 17626                 panic("dp8390: remote dma failed to complete", NO_NUM);
  1715. 17627         }
  1716. 17628 }
  1717. 17631 /*===========================================================================*
  1718. 17632  *                              dp_pio16_user2nic                            *
  1719. 17633  *===========================================================================*/
  1720. 17634 static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
  1721. 17635 dpeth_t *dep;
  1722. 17636 iovec_dat_t *iovp;
  1723. 17637 vir_bytes offset;
  1724. 17638 int nic_addr;
  1725. 17639 vir_bytes count;
  1726. 17640 {
  1727. 17641         phys_bytes phys_user;
  1728. 17642         vir_bytes ecount;
  1729. 17643         int bytes, i;
  1730. 17644         u8_t two_bytes[2];
  1731. 17645         phys_bytes phys_2bytes;
  1732. 17646         int odd_byte;
  1733. 17647
  1734. 17648         ecount= (count+1) & ~1;
  1735. 17649         phys_2bytes = vir2phys(two_bytes);
  1736. 17650         odd_byte= 0;
  1737. 17651
  1738. 17652         outb_reg0(dep, DP_ISR, ISR_RDC);
  1739. 17653         outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
  1740. 17654         outb_reg0(dep, DP_RBCR1, ecount >> 8);
  1741. 17655         outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1742. 17656         outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1743. 17657         outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
  1744. 17658
  1745. 17659         i= 0;
  1746. 17660         while (count > 0)
  1747. 17661         {
  1748. 17662                 if (i >= IOVEC_NR)
  1749. 17663                 {
  1750. 17664                         dp_next_iovec(iovp);
  1751. 17665                         i= 0;
  1752. 17666                         continue;
  1753. 17667                 }
  1754. 17668                 assert(i < iovp->iod_iovec_s);
  1755. 17669                 if (offset >= iovp->iod_iovec[i].iov_size)
  1756. 17670                 {
  1757. 17671                         offset -= iovp->iod_iovec[i].iov_size;
  1758. 17672                         i++;
  1759. 17673                         continue;
  1760. 17674                 }
  1761. 17675                 bytes = iovp->iod_iovec[i].iov_size - offset;
  1762. 17676                 if (bytes > count)
  1763. 17677                         bytes = count;
  1764. 17678
  1765. 17679                 phys_user = numap(iovp->iod_proc_nr,
  1766. 17680                         iovp->iod_iovec[i].iov_addr + offset, bytes);
  1767. 17681                 if (!phys_user)
  1768. 17682                         panic("dp8390: umap failedn", NO_NUM);
  1769. 17683                 if (odd_byte)
  1770. 17684                 {
  1771. 17685                         phys_copy(phys_user, phys_2bytes+1,
  1772. 17686                                 (phys_bytes) 1);
  1773. 17687                         out_word(dep->de_data_port, *(u16_t *)two_bytes);
  1774. 17688                         count--;
  1775. 17689                         offset++;
  1776. 17690                         bytes--;
  1777. 17691                         phys_user++;
  1778. 17692                         odd_byte= 0;
  1779. 17693                         if (!bytes)
  1780. 17694                                 continue;
  1781. 17695                 }
  1782. 17696                 ecount= bytes & ~1;
  1783. 17697                 if (ecount != 0)
  1784. 17698                 {
  1785. 17699                         port_write(dep->de_data_port, phys_user, ecount);
  1786. 17700                         count -= ecount;
  1787. 17701                         offset += ecount;
  1788. 17702                         bytes -= ecount;
  1789. 17703                         phys_user += ecount;
  1790. 17704                 }
  1791. 17705                 if (bytes)
  1792. 17706                 {
  1793. 17707                         assert(bytes == 1);
  1794. 17708                         phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);
  1795. 17709                         count--;
  1796. 17710                         offset++;
  1797. 17711                         bytes--;
  1798. 17712                         phys_user++;
  1799. 17713                         odd_byte= 1;
  1800. 17714                 }
  1801. 17715         }
  1802. 17716         assert(count == 0);
  1803. 17717
  1804. 17718         if (odd_byte)
  1805. 17719                 out_word(dep->de_data_port, *(u16_t *)two_bytes);
  1806. 17720
  1807. 17721         for (i= 0; i<100; i++)
  1808. 17722         {
  1809. 17723                 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
  1810. 17724                         break;
  1811. 17725         }
  1812. 17726         if (i == 100)
  1813. 17727         {
  1814. 17728                 panic("dp8390: remote dma failed to complete", NO_NUM);
  1815. 17729         }
  1816. 17730 }
  1817. 17733 /*===========================================================================*
  1818. 17734  *                              dp_nic2user                                  *
  1819. 17735  *===========================================================================*/
  1820. 17736 static void dp_nic2user(dep, nic_addr, iovp, offset, count)
  1821. 17737 dpeth_t *dep;
  1822. 17738 int nic_addr;
  1823. 17739 iovec_dat_t *iovp;
  1824. 17740 vir_bytes offset;
  1825. 17741 vir_bytes count;
  1826. 17742 {
  1827. 17743         phys_bytes phys_hw, phys_user;
  1828. 17744         int bytes, i;
  1829. 17745
  1830. 17746         phys_hw = dep->de_linmem + nic_addr;
  1831. 17747
  1832. 17748         i= 0;
  1833. 17749         while (count > 0)
  1834. 17750         {
  1835. 17751                 if (i >= IOVEC_NR)
  1836. 17752                 {
  1837. 17753                         dp_next_iovec(iovp);
  1838. 17754                         i= 0;
  1839. 17755                         continue;
  1840. 17756                 }
  1841. 17757                 assert(i < iovp->iod_iovec_s);
  1842. 17758                 if (offset >= iovp->iod_iovec[i].iov_size)
  1843. 17759                 {
  1844. 17760                         offset -= iovp->iod_iovec[i].iov_size;
  1845. 17761                         i++;
  1846. 17762                         continue;
  1847. 17763                 }
  1848. 17764                 bytes = iovp->iod_iovec[i].iov_size - offset;
  1849. 17765                 if (bytes > count)
  1850. 17766                         bytes = count;
  1851. 17767
  1852. 17768                 phys_user = numap(iovp->iod_proc_nr,
  1853. 17769                         iovp->iod_iovec[i].iov_addr + offset, bytes);
  1854. 17770                 if (!phys_user)
  1855. 17771                         panic("dp8390: umap failedn", NO_NUM);
  1856. 17772                 phys_copy(phys_hw, phys_user, (phys_bytes) bytes);
  1857. 17773                 count -= bytes;
  1858. 17774                 phys_hw += bytes;
  1859. 17775                 offset += bytes;
  1860. 17776         }
  1861. 17777         assert(count == 0);
  1862. 17778 }
  1863. 17781 /*===========================================================================*
  1864. 17782  *                              dp_pio8_nic2user                             *
  1865. 17783  *===========================================================================*/
  1866. 17784 static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
  1867. 17785 dpeth_t *dep;
  1868. 17786 int nic_addr;
  1869. 17787 iovec_dat_t *iovp;
  1870. 17788 vir_bytes offset;
  1871. 17789 vir_bytes count;
  1872. 17790 {
  1873. 17791         phys_bytes phys_user;
  1874. 17792         int bytes, i;
  1875. 17793
  1876. 17794         outb_reg0(dep, DP_RBCR0, count & 0xFF);
  1877. 17795         outb_reg0(dep, DP_RBCR1, count >> 8);
  1878. 17796         outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1879. 17797         outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1880. 17798         outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  1881. 17799
  1882. 17800         i= 0;
  1883. 17801         while (count > 0)
  1884. 17802         {
  1885. 17803                 if (i >= IOVEC_NR)
  1886. 17804                 {
  1887. 17805                         dp_next_iovec(iovp);
  1888. 17806                         i= 0;
  1889. 17807                         continue;
  1890. 17808                 }
  1891. 17809                 assert(i < iovp->iod_iovec_s);
  1892. 17810                 if (offset >= iovp->iod_iovec[i].iov_size)
  1893. 17811                 {
  1894. 17812                         offset -= iovp->iod_iovec[i].iov_size;
  1895. 17813                         i++;
  1896. 17814                         continue;
  1897. 17815                 }
  1898. 17816                 bytes = iovp->iod_iovec[i].iov_size - offset;
  1899. 17817                 if (bytes > count)
  1900. 17818                         bytes = count;
  1901. 17819
  1902. 17820                 phys_user = numap(iovp->iod_proc_nr,
  1903. 17821                         iovp->iod_iovec[i].iov_addr + offset, bytes);
  1904. 17822                 if (!phys_user)
  1905. 17823                         panic("dp8390: umap failedn", NO_NUM);
  1906. 17824                 port_read_byte(dep->de_data_port, phys_user, bytes);
  1907. 17825                 count -= bytes;
  1908. 17826                 offset += bytes;
  1909. 17827         }
  1910. 17828         assert(count == 0);
  1911. 17829 }
  1912. 17832 /*===========================================================================*
  1913. 17833  *                              dp_pio16_nic2user                            *
  1914. 17834  *===========================================================================*/
  1915. 17835 static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
  1916. 17836 dpeth_t *dep;
  1917. 17837 int nic_addr;
  1918. 17838 iovec_dat_t *iovp;
  1919. 17839 vir_bytes offset;
  1920. 17840 vir_bytes count;
  1921. 17841 {
  1922. 17842         phys_bytes phys_user;
  1923. 17843         vir_bytes ecount;
  1924. 17844         int bytes, i;
  1925. 17845         u8_t two_bytes[2];
  1926. 17846         phys_bytes phys_2bytes;
  1927. 17847         int odd_byte;
  1928. 17848
  1929. 17849         ecount= (count+1) & ~1;
  1930. 17850         phys_2bytes = vir2phys(two_bytes);
  1931. 17851         odd_byte= 0;
  1932. 17852
  1933. 17853         outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
  1934. 17854         outb_reg0(dep, DP_RBCR1, ecount >> 8);
  1935. 17855         outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1936. 17856         outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1937. 17857         outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  1938. 17858
  1939. 17859         i= 0;
  1940. 17860         while (count > 0)
  1941. 17861         {
  1942. 17862                 if (i >= IOVEC_NR)
  1943. 17863                 {
  1944. 17864                         dp_next_iovec(iovp);
  1945. 17865                         i= 0;
  1946. 17866                         continue;
  1947. 17867                 }
  1948. 17868                 assert(i < iovp->iod_iovec_s);
  1949. 17869                 if (offset >= iovp->iod_iovec[i].iov_size)
  1950. 17870                 {
  1951. 17871                         offset -= iovp->iod_iovec[i].iov_size;
  1952. 17872                         i++;
  1953. 17873                         continue;
  1954. 17874                 }
  1955. 17875                 bytes = iovp->iod_iovec[i].iov_size - offset;
  1956. 17876                 if (bytes > count)
  1957. 17877                         bytes = count;
  1958. 17878
  1959. 17879                 phys_user = numap(iovp->iod_proc_nr,
  1960. 17880                         iovp->iod_iovec[i].iov_addr + offset, bytes);
  1961. 17881                 if (!phys_user)
  1962. 17882                         panic("dp8390: umap failedn", NO_NUM);
  1963. 17883                 if (odd_byte)
  1964. 17884                 {
  1965. 17885                         phys_copy(phys_2bytes+1, phys_user, (phys_bytes) 1);
  1966. 17886                         count--;
  1967. 17887                         offset++;
  1968. 17888                         bytes--;
  1969. 17889                         phys_user++;
  1970. 17890                         odd_byte= 0;
  1971. 17891                         if (!bytes)
  1972. 17892                                 continue;
  1973. 17893                 }
  1974. 17894                 ecount= bytes & ~1;
  1975. 17895                 if (ecount != 0)
  1976. 17896                 {
  1977. 17897                         port_read(dep->de_data_port, phys_user, ecount);
  1978. 17898                         count -= ecount;
  1979. 17899                         offset += ecount;
  1980. 17900                         bytes -= ecount;
  1981. 17901                         phys_user += ecount;
  1982. 17902                 }
  1983. 17903                 if (bytes)
  1984. 17904                 {
  1985. 17905                         assert(bytes == 1);
  1986. 17906                         *(u16_t *)two_bytes= in_word(dep->de_data_port);
  1987. 17907                         phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);
  1988. 17908                         count--;
  1989. 17909                         offset++;
  1990. 17910                         bytes--;
  1991. 17911                         phys_user++;
  1992. 17912                         odd_byte= 1;
  1993. 17913                 }
  1994. 17914         }
  1995. 17915         assert(count == 0);
  1996. 17916 }
  1997. 17919 /*===========================================================================*
  1998. 17920  *                              dp_next_iovec                                        *
  1999. 17921  *===========================================================================*/
  2000. 17922 static void dp_next_iovec(iovp)
  2001. 17923 iovec_dat_t *iovp;
  2002. 17924 {
  2003. 17925         assert(iovp->iod_iovec_s > IOVEC_NR);
  2004. 17926
  2005. 17927         iovp->iod_iovec_s -= IOVEC_NR;
  2006. 17928
  2007. 17929         iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
  2008. 17930
  2009. 17931         get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr, 
  2010. 17932                 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
  2011. 17933                 sizeof(iovec_t), iovp->iod_iovec); 
  2012. 17934 }
  2013. 17937 /*===========================================================================*
  2014. 17938  *                              dp_handler                                   *
  2015. 17939  *===========================================================================*/
  2016. 17940 static int dp_handler(irq)
  2017. 17941 int irq;
  2018. 17942 {
  2019. 17943 /* DP8390 interrupt, send message and reenable interrupts. */
  2020. 17944
  2021. 17945         assert(irq >= 0 && irq < NR_IRQ_VECTORS);
  2022. 17946         int_pending[irq]= 1;
  2023. 17947         interrupt(dpeth_tasknr);
  2024. 17948         return 1;
  2025. 17949 }
  2026. 17951 /*===========================================================================*
  2027. 17952  *                              conf_hw                                      *
  2028. 17953  *===========================================================================*/
  2029. 17954 static void conf_hw(dep)
  2030. 17955 dpeth_t *dep;
  2031. 17956 {
  2032. 17957         static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0        /* ,... */ };
  2033. 17958
  2034. 17959         int ifnr;
  2035. 17960         dp_conf_t *dcp;
  2036. 17961
  2037. 17962         dep->de_mode= DEM_DISABLED;     /* Superfluous */
  2038. 17963         ifnr= dep-de_table;
  2039. 17964
  2040. 17965         dcp= &dp_conf[ifnr];
  2041. 17966         update_conf(dep, dcp);
  2042. 17967         if (dep->de_mode != DEM_ENABLED)
  2043. 17968                         return;
  2044. 17969         if (!wdeth_probe(dep) && !ne_probe(dep))
  2045. 17970         {
  2046. 17971                 printf("dp8390: warning no ethernet card found at 0x%xn", 
  2047. 17972                         dep->de_base_port);
  2048. 17973                 dep->de_mode= DEM_DISABLED;
  2049. 17974                 return;
  2050. 17975         }
  2051. 17976
  2052. 17977         /* Allocate a memory segment, programmed I/O should set the
  2053. 17978          * memory segment (linmem) to zero.
  2054. 17979          */
  2055. 17980         if (dep->de_linmem != 0)
  2056. 17981         {
  2057. 17982                 if (protected_mode)
  2058. 17983                 {
  2059. 17984                         init_dataseg(&gdt[dcp->dpc_prot_sel / DESC_SIZE],
  2060. 17985                                 dep->de_linmem, dep->de_ramsize,
  2061. 17986                                 TASK_PRIVILEGE);
  2062. 17987                         dep->de_memsegm= dcp->dpc_prot_sel;
  2063. 17988                 }
  2064. 17989                 else
  2065. 17990                 {
  2066. 17991                         dep->de_memsegm= physb_to_hclick(dep->de_linmem);
  2067. 17992                 }
  2068. 17993         }
  2069. 17994
  2070. 17995 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
  2071. 17996
  2072. 17997         dep->de_flags = DEF_EMPTY;
  2073. 17998         dep->de_stat = empty_stat;
  2074. 17999 }
  2075. 18002 /*===========================================================================*
  2076. 18003  *                              update_conf                                  *
  2077. 18004  *===========================================================================*/
  2078. 18005 static void update_conf(dep, dcp)
  2079. 18006 dpeth_t *dep;
  2080. 18007 dp_conf_t *dcp;
  2081. 18008 {
  2082. 18009         long v;
  2083. 18010         static char dpc_fmt[] = "x:d:x";
  2084. 18011
  2085. 18012         /* Get the default settings and modify them from the environment. */
  2086. 18013         dep->de_mode= DEM_SINK;
  2087. 18014         v= dcp->dpc_port;
  2088. 18015         switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &v, 0x000L, 0x3FFL)) {
  2089. 18016         case EP_OFF:
  2090. 18017                 dep->de_mode= DEM_DISABLED;
  2091. 18018                 break;
  2092. 18019         case EP_ON:
  2093. 18020         case EP_SET:
  2094. 18021                 dep->de_mode= DEM_ENABLED;      /* Might become disabled if 
  2095. 18022                                                  * all probes fail */
  2096. 18023                 break;
  2097. 18024         }
  2098. 18025         dep->de_base_port= v;
  2099. 18026
  2100. 18027         v= dcp->dpc_irq | DEI_DEFAULT;
  2101. 18028         (void) env_parse(dcp->dpc_envvar, dpc_fmt, 1, &v, 0L,
  2102. 18029                                                 (long) NR_IRQ_VECTORS - 1);
  2103. 18030         dep->de_irq= v;
  2104. 18031
  2105. 18032         v= dcp->dpc_mem;
  2106. 18033         (void) env_parse(dcp->dpc_envvar, dpc_fmt, 2, &v, 0L, LONG_MAX);
  2107. 18034         dep->de_linmem= v;
  2108. 18035 }
  2109. 18038 /*===========================================================================*
  2110. 18039  *                              calc_iovec_size                              *
  2111. 18040  *===========================================================================*/
  2112. 18041 static int calc_iovec_size(iovp)
  2113. 18042 iovec_dat_t *iovp;
  2114. 18043 {
  2115. 18044         /* Calculate the size of a request. Note that the iovec_dat
  2116. 18045          * structure will be unusable after calc_iovec_size.
  2117. 18046          */
  2118. 18047         int size;
  2119. 18048         int i;
  2120. 18049
  2121. 18050         size= 0;
  2122. 18051         i= 0;
  2123. 18052         while (i < iovp->iod_iovec_s)
  2124. 18053         {
  2125. 18054                 if (i >= IOVEC_NR)
  2126. 18055                 {
  2127. 18056                         dp_next_iovec(iovp);
  2128. 18057                         i= 0;
  2129. 18058                         continue;
  2130. 18059                 }
  2131. 18060                 size += iovp->iod_iovec[i].iov_size;
  2132. 18061                 i++;
  2133. 18062         }
  2134. 18063         return size;
  2135. 18064 }
  2136. 18067 /*===========================================================================*
  2137. 18068  *                              reply                                        *
  2138. 18069  *===========================================================================*/
  2139. 18070 static void reply(dep, err, may_block)
  2140. 18071 dpeth_t *dep;
  2141. 18072 int err;
  2142. 18073 int may_block;
  2143. 18074 {
  2144. 18075         message reply;
  2145. 18076         int status;
  2146. 18077         int r;
  2147. 18078
  2148. 18079         status = 0;
  2149. 18080         if (dep->de_flags & DEF_PACK_SEND)
  2150. 18081                 status |= DL_PACK_SEND;
  2151. 18082         if (dep->de_flags & DEF_PACK_RECV)
  2152. 18083                 status |= DL_PACK_RECV;
  2153. 18084
  2154. 18085         reply.m_type = DL_TASK_REPLY;
  2155. 18086         reply.DL_PORT = dep - de_table;
  2156. 18087         reply.DL_PROC = dep->de_client;
  2157. 18088         reply.DL_STAT = status | ((u32_t) err << 16);
  2158. 18089         reply.DL_COUNT = dep->de_read_s;
  2159. 18090         reply.DL_CLCK = get_uptime();
  2160. 18091         r= send(dep->de_client, &reply);
  2161. 18092 #if 0
  2162. 18093         /* XXX  What is the reason that this doesn't happen? */
  2163. 18094         if (result == ELOCKED && may_block)
  2164. 18095                 return;
  2165. 18096 #endif
  2166. 18097         if (r < 0)
  2167. 18098                 panic("dp8390: send failed:", r);
  2168. 18099         
  2169. 18100         dep->de_read_s = 0;
  2170. 18101         dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
  2171. 18102 }
  2172. 18105 /*===========================================================================*
  2173. 18106  *                              mess_reply                                   *
  2174. 18107  *===========================================================================*/
  2175. 18108 static void mess_reply(req, reply_mess)
  2176. 18109 message *req;
  2177. 18110 message *reply_mess;
  2178. 18111 {
  2179. 18112         if (send(req->m_source, reply_mess) != OK)
  2180. 18113                 panic("dp8390: unable to mess_reply", NO_NUM);
  2181. 18114 }
  2182. 18117 /*===========================================================================*
  2183. 18118  *                              get_userdata                                 *
  2184. 18119  *===========================================================================*/
  2185. 18120 static void get_userdata(user_proc, user_addr, count, loc_addr)
  2186. 18121 int user_proc;
  2187. 18122 vir_bytes user_addr;
  2188. 18123 vir_bytes count;
  2189. 18124 void *loc_addr;
  2190. 18125 {
  2191. 18126         phys_bytes src;
  2192. 18127
  2193. 18128         src = numap(user_proc, user_addr, count);
  2194. 18129         if (!src)
  2195. 18130                 panic("dp8390: umap failed", NO_NUM);
  2196. 18131
  2197. 18132         phys_copy(src, vir2phys(loc_addr), (phys_bytes) count);
  2198. 18133 }
  2199. 18136 /*===========================================================================*
  2200. 18137  *                              put_userdata                                 *
  2201. 18138  *===========================================================================*/
  2202. 18139 static void put_userdata(user_proc, user_addr, count, loc_addr)
  2203. 18140 int user_proc;
  2204. 18141 vir_bytes user_addr;
  2205. 18142 vir_bytes count;
  2206. 18143 void *loc_addr;
  2207. 18144 {
  2208. 18145         phys_bytes dst;
  2209. 18146
  2210. 18147         dst = numap(user_proc, user_addr, count);
  2211. 18148         if (!dst)
  2212. 18149                 panic("dp8390: umap failed", NO_NUM);
  2213. 18150
  2214. 18151         phys_copy(vir2phys(loc_addr), dst, (phys_bytes) count);
  2215. 18152 }
  2216. 18154 #endif /* ENABLE_NETWORKING */
  2217. 18155
  2218. 18156 /*
  2219. 18157  * $PchHeader: /mount/hd2/minix/sys/kernel/ibm/RCS/dp8390.c,v 1.4 1995/06/13 08:10:42 philip Exp $
  2220. 18158  */
  2221. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2222. src/kernel/driver.c    
  2223. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2224. 18200 /* This file contains device independent device driver interface.
  2225. 18201  *                                                      Author: Kees J. Bot.
  2226. 18202  *
  2227. 18203  * The drivers support the following operations (using message format m2):
  2228. 18204  *
  2229. 18205  *    m_type      DEVICE    PROC_NR     COUNT    POSITION  ADRRESS
  2230. 18206  * ----------------------------------------------------------------
  2231. 18207  * |  DEV_OPEN  | device  | proc nr |         |         |         |
  2232. 18208  * |------------+---------+---------+---------+---------+---------|
  2233. 18209  * |  DEV_CLOSE | device  | proc nr |         |         |         |
  2234. 18210  * |------------+---------+---------+---------+---------+---------|
  2235. 18211  * |  DEV_READ  | device  | proc nr |  bytes  |  offset | buf ptr |
  2236. 18212  * |------------+---------+---------+---------+---------+---------|
  2237. 18213  * |  DEV_WRITE | device  | proc nr |  bytes  |  offset | buf ptr |
  2238. 18214  * |------------+---------+---------+---------+---------+---------|
  2239. 18215  * |SCATTERED_IO| device  | proc nr | requests|         | iov ptr |
  2240. 18216  * ----------------------------------------------------------------
  2241. 18217  * |  DEV_IOCTL | device  | proc nr |func code|         | buf ptr |
  2242. 18218  * ----------------------------------------------------------------
  2243. 18219  *
  2244. 18220  * The file contains one entry point:
  2245. 18221  *
  2246. 18222  *   driver_task:       called by the device dependent task entry
  2247. 18223  *
  2248. 18224  *
  2249. 18225  * Constructed 92/04/02 by Kees J. Bot from the old AT wini and floppy driver.
  2250. 18226  */
  2251. 18227
  2252. 18228 #include "kernel.h"
  2253. 18229 #include <sys/ioctl.h>
  2254. 18230 #include "driver.h"
  2255. 18231
  2256. 18232 #if (CHIP == INTEL)
  2257. 18233 #if ENABLE_ADAPTEC_SCSI && DMA_BUF_SIZE < 2048
  2258. 18234 /* A bit extra scratch for the Adaptec driver. */
  2259. 18235 #define BUF_EXTRA       (2048 - DMA_BUF_SIZE)
  2260. 18236 #else
  2261. 18237 #define BUF_EXTRA       0
  2262. 18238 #endif
  2263. 18239
  2264. 18240 /* Claim space for variables. */
  2265. 18241 PRIVATE u8_t buffer[(unsigned) 2 * DMA_BUF_SIZE + BUF_EXTRA];
  2266. 18242 u8_t *tmp_buf;                  /* the DMA buffer eventually */
  2267. 18243 phys_bytes tmp_phys;            /* phys address of DMA buffer */
  2268. 18244
  2269. 18245 #else /* CHIP != INTEL */
  2270. 18246
  2271. 18247 /* Claim space for variables. */
  2272. 18248 u8_t tmp_buf[DMA_BUF_SIZE];     /* the DMA buffer */
  2273. 18249 phys_bytes tmp_phys;            /* phys address of DMA buffer */
  2274. 18250
  2275. 18251 #endif /* CHIP != INTEL */
  2276. 18252
  2277. 18253 FORWARD _PROTOTYPE( void init_buffer, (void) );
  2278. 18254
  2279. 18255
  2280. 18256 /*===========================================================================*
  2281. 18257  *                              driver_task                                  *
  2282. 18258  *===========================================================================*/
  2283. 18259 PUBLIC void driver_task(dp)
  2284. 18260 struct driver *dp;      /* Device dependent entry points. */
  2285. 18261 {
  2286. 18262 /* Main program of any device driver task. */
  2287. 18263
  2288. 18264   int r, caller, proc_nr;
  2289. 18265   message mess;
  2290. 18266
  2291. 18267   init_buffer();        /* Get a DMA buffer. */
  2292. 18268
  2293. 18269
  2294. 18270   /* Here is the main loop of the disk task.  It waits for a message, carries
  2295. 18271    * it out, and sends a reply.
  2296. 18272    */
  2297. 18273
  2298. 18274   while (TRUE) {
  2299. 18275         /* First wait for a request to read or write a disk block. */
  2300. 18276         receive(ANY, &mess);
  2301. 18277
  2302. 18278         caller = mess.m_source;
  2303. 18279         proc_nr = mess.PROC_NR;
  2304. 18280
  2305. 18281         switch (caller) {
  2306. 18282         case HARDWARE:
  2307. 18283                 /* Leftover interrupt. */
  2308. 18284                 continue;
  2309. 18285         case FS_PROC_NR:
  2310. 18286                 /* The only legitimate caller. */
  2311. 18287                 break;
  2312. 18288         default:
  2313. 18289                 printf("%s: got message from %dn", (*dp->dr_name)(), caller);
  2314. 18290                 continue;
  2315. 18291         }
  2316. 18292
  2317. 18293         /* Now carry out the work. */
  2318. 18294         switch(mess.m_type) {
  2319. 18295             case DEV_OPEN:      r = (*dp->dr_open)(dp, &mess);  break;
  2320. 18296             case DEV_CLOSE:     r = (*dp->dr_close)(dp, &mess); break;
  2321. 18297             case DEV_IOCTL:     r = (*dp->dr_ioctl)(dp, &mess); break;
  2322. 18298
  2323. 18299             case DEV_READ:
  2324. 18300             case DEV_WRITE:     r = do_rdwt(dp, &mess);         break;
  2325. 18301
  2326. 18302             case SCATTERED_IO:  r = do_vrdwt(dp, &mess);        break;
  2327. 18303             default:            r = EINVAL;                     break;
  2328. 18304         }
  2329. 18305
  2330. 18306         /* Clean up leftover state. */
  2331. 18307         (*dp->dr_cleanup)();
  2332. 18308
  2333. 18309         /* Finally, prepare and send the reply message. */
  2334. 18310         mess.m_type = TASK_REPLY;
  2335. 18311         mess.REP_PROC_NR = proc_nr;
  2336. 18312
  2337. 18313         mess.REP_STATUS = r;    /* # of bytes transferred or error code */
  2338. 18314         send(caller, &mess);    /* send reply to caller */
  2339. 18315   }
  2340. 18316 }
  2341. 18319 /*===========================================================================*
  2342. 18320  *                              init_buffer                                  *
  2343. 18321  *===========================================================================*/
  2344. 18322 PRIVATE void init_buffer()
  2345. 18323 {
  2346. 18324 /* Select a buffer that can safely be used for dma transfers.  It may also
  2347. 18325  * be used to read partition tables and such.  Its absolute address is
  2348. 18326  * 'tmp_phys', the normal address is 'tmp_buf'.
  2349. 18327  */
  2350. 18328
  2351. 18329 #if (CHIP == INTEL)
  2352. 18330   tmp_buf = buffer;
  2353. 18331   tmp_phys = vir2phys(buffer);
  2354. 18332
  2355. 18333   if (tmp_phys == 0) panic("no DMA buffer", NO_NUM);
  2356. 18334
  2357. 18335   if (dma_bytes_left(tmp_phys) < DMA_BUF_SIZE) {
  2358. 18336         /* First half of buffer crosses a 64K boundary, can't DMA into that */
  2359. 18337         tmp_buf += DMA_BUF_SIZE;
  2360. 18338         tmp_phys += DMA_BUF_SIZE;
  2361. 18339   }
  2362. 18340 #else /* CHIP != INTEL */
  2363. 18341   tmp_phys = vir2phys(tmp_buf);
  2364. 18342 #endif /* CHIP != INTEL */
  2365. 18343 }
  2366. 18346 /*===========================================================================*
  2367. 18347  *                              do_rdwt                                      *
  2368. 18348  *===========================================================================*/
  2369. 18349 PUBLIC int do_rdwt(dp, m_ptr)
  2370. 18350 struct driver *dp;              /* device dependent entry points */
  2371. 18351 message *m_ptr;                 /* pointer to read or write message */
  2372. 18352 {
  2373. 18353 /* Carry out a single read or write request. */
  2374. 18354   struct iorequest_s ioreq;
  2375. 18355   int r;
  2376. 18356
  2377. 18357   if (m_ptr->COUNT <= 0) return(EINVAL);
  2378. 18358
  2379. 18359   if ((*dp->dr_prepare)(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
  2380. 18360
  2381. 18361   ioreq.io_request = m_ptr->m_type;
  2382. 18362   ioreq.io_buf = m_ptr->ADDRESS;
  2383. 18363   ioreq.io_position = m_ptr->POSITION;
  2384. 18364   ioreq.io_nbytes = m_ptr->COUNT;
  2385. 18365
  2386. 18366   r = (*dp->dr_schedule)(m_ptr->PROC_NR, &ioreq);
  2387. 18367
  2388. 18368   if (r == OK) (void) (*dp->dr_finish)();
  2389. 18369
  2390. 18370   r = ioreq.io_nbytes;
  2391. 18371   return(r < 0 ? r : m_ptr->COUNT - r);
  2392. 18372 }
  2393. 18375 /*==========================================================================*
  2394. 18376  *                              do_vrdwt                                    *
  2395. 18377  *==========================================================================*/
  2396. 18378 PUBLIC int do_vrdwt(dp, m_ptr)
  2397. 18379 struct driver *dp;      /* device dependent entry points */
  2398. 18380 message *m_ptr;         /* pointer to read or write message */
  2399. 18381 {
  2400. 18382 /* Fetch a vector of i/o requests.  Handle requests one at a time.  Return
  2401. 18383  * status in the vector.
  2402. 18384  */
  2403. 18385
  2404. 18386   struct iorequest_s *iop;
  2405. 18387   static struct iorequest_s iovec[NR_IOREQS];
  2406. 18388   phys_bytes iovec_phys;
  2407. 18389   unsigned nr_requests;
  2408. 18390   int request;
  2409. 18391   int r;
  2410. 18392   phys_bytes user_iovec_phys;
  2411. 18393
  2412. 18394   nr_requests = m_ptr->COUNT;
  2413. 18395
  2414. 18396   if (nr_requests > sizeof iovec / sizeof iovec[0])
  2415. 18397         panic("FS passed too big an I/O vector", nr_requests);
  2416. 18398
  2417. 18399   iovec_phys = vir2phys(iovec);
  2418. 18400   user_iovec_phys = numap(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS,
  2419. 18401                          (vir_bytes) (nr_requests * sizeof iovec[0]));
  2420. 18402
  2421. 18403   if (user_iovec_phys == 0)
  2422. 18404         panic("FS passed a bad I/O vector", (int) m_ptr->ADDRESS);
  2423. 18405
  2424. 18406   phys_copy(user_iovec_phys, iovec_phys,
  2425. 18407                             (phys_bytes) nr_requests * sizeof iovec[0]);
  2426. 18408
  2427. 18409   if ((*dp->dr_prepare)(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
  2428. 18410
  2429. 18411   for (request = 0, iop = iovec; request < nr_requests; request++, iop++) {
  2430. 18412         if ((r = (*dp->dr_schedule)(m_ptr->PROC_NR, iop)) != OK) break;
  2431. 18413   }
  2432. 18414
  2433. 18415   if (r == OK) (void) (*dp->dr_finish)();
  2434. 18416
  2435. 18417   phys_copy(iovec_phys, user_iovec_phys,
  2436. 18418                             (phys_bytes) nr_requests * sizeof iovec[0]);
  2437. 18419   return(OK);
  2438. 18420 }
  2439. 18423 /*===========================================================================*
  2440. 18424  *                              no_name                                      *
  2441. 18425  *===========================================================================*/
  2442. 18426 PUBLIC char *no_name()
  2443. 18427 {
  2444. 18428 /* If no specific name for the device. */
  2445. 18429
  2446. 18430   return(tasktab[proc_number(proc_ptr) + NR_TASKS].name);
  2447. 18431 }
  2448. 18434 /*============================================================================*
  2449. 18435  *                              do_nop                                        *
  2450. 18436  *============================================================================*/
  2451. 18437 PUBLIC int do_nop(dp, m_ptr)
  2452. 18438 struct driver *dp;
  2453. 18439 message *m_ptr;
  2454. 18440 {
  2455. 18441 /* Nothing there, or nothing to do. */
  2456. 18442
  2457. 18443   switch (m_ptr->m_type) {
  2458. 18444   case DEV_OPEN:        return(ENODEV);
  2459. 18445   case DEV_CLOSE:       return(OK);
  2460. 18446   case DEV_IOCTL:       return(ENOTTY);
  2461. 18447   default:              return(EIO);
  2462. 18448   }
  2463. 18449 }
  2464. 18452 /*===========================================================================*
  2465. 18453  *                              nop_finish                                   *
  2466. 18454  *===========================================================================*/
  2467. 18455 PUBLIC int nop_finish()
  2468. 18456 {
  2469. 18457 /* Nothing to finish, all the work has been done by dp->dr_schedule. */
  2470. 18458   return(OK);
  2471. 18459 }
  2472. 18462 /*===========================================================================*
  2473. 18463  *                              nop_cleanup                                  *
  2474. 18464  *===========================================================================*/
  2475. 18465 PUBLIC void nop_cleanup()
  2476. 18466 {
  2477. 18467 /* Nothing to clean up. */
  2478. 18468 }
  2479. 18471 /*===========================================================================*
  2480. 18472  *                              clock_mess                                   *
  2481. 18473  *===========================================================================*/
  2482. 18474 PUBLIC void clock_mess(ticks, func)
  2483. 18475 int ticks;                      /* how many clock ticks to wait */
  2484. 18476 watchdog_t func;                /* function to call upon time out */
  2485. 18477 {
  2486. 18478 /* Send the clock task a message. */
  2487. 18479
  2488. 18480   message mess;
  2489. 18481
  2490. 18482   mess.m_type = SET_ALARM;
  2491. 18483   mess.CLOCK_PROC_NR = proc_number(proc_ptr);
  2492. 18484   mess.DELTA_TICKS = (long) ticks;
  2493. 18485   mess.FUNC_TO_CALL = (sighandler_t) func;
  2494. 18486   sendrec(CLOCK, &mess);
  2495. 18487 }
  2496. 18490 /*============================================================================*
  2497. 18491  *                              do_diocntl                                    *
  2498. 18492  *============================================================================*/
  2499. 18493 PUBLIC int do_diocntl(dp, m_ptr)
  2500. 18494 struct driver *dp;
  2501. 18495 message *m_ptr;                 /* pointer to ioctl request */
  2502. 18496 {
  2503. 18497 /* Carry out a partition setting/getting request. */
  2504. 18498   struct device *dv;
  2505. 18499   phys_bytes user_phys, entry_phys;
  2506. 18500   struct partition entry;
  2507. 18501
  2508. 18502   if (m_ptr->REQUEST != DIOCSETP && m_ptr->REQUEST != DIOCGETP) return(ENOTTY);
  2509. 18503
  2510. 18504   /* Decode the message parameters. */
  2511. 18505   if ((dv = (*dp->dr_prepare)(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
  2512. 18506
  2513. 18507   user_phys = numap(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS, sizeof(entry));
  2514. 18508   if (user_phys == 0) return(EFAULT);
  2515. 18509
  2516. 18510   entry_phys = vir2phys(&entry);
  2517. 18511
  2518. 18512   if (m_ptr->REQUEST == DIOCSETP) {
  2519. 18513         /* Copy just this one partition table entry. */
  2520. 18514         phys_copy(user_phys, entry_phys, (phys_bytes) sizeof(entry));
  2521. 18515         dv->dv_base = entry.base;
  2522. 18516         dv->dv_size = entry.size;
  2523. 18517   } else {
  2524. 18518         /* Return a partition table entry and the geometry of the drive. */
  2525. 18519         entry.base = dv->dv_base;
  2526. 18520         entry.size = dv->dv_size;
  2527. 18521         (*dp->dr_geometry)(&entry);
  2528. 18522         phys_copy(entry_phys, user_phys, (phys_bytes) sizeof(entry));
  2529. 18523   }
  2530. 18524   return(OK);
  2531. 18525 }
  2532. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2533. src/kernel/drvlib.c    
  2534. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2535. 18600 /* IBM device driver utility functions.                 Author: Kees J. Bot
  2536. 18601  *                                                              7 Dec 1995
  2537. 18602  * Entry point:
  2538. 18603  *   partition: partition a disk to the partition table(s) on it.
  2539. 18604  */
  2540. 18605
  2541. 18606 #include "kernel.h"
  2542. 18607 #include "driver.h"
  2543. 18608 #include "drvlib.h"
  2544. 18609
  2545. 18610
  2546. 18611 FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
  2547. 18612                                                 unsigned long extbase) );
  2548. 18613 FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
  2549. 18614                         unsigned long offset, struct part_entry *table) );
  2550. 18615 FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
  2551. 18616
  2552. 18617
  2553. 18618 /*============================================================================*
  2554. 18619  *                              partition                                     *
  2555. 18620  *============================================================================*/
  2556. 18621 PUBLIC void partition(dp, device, style)
  2557. 18622 struct driver *dp;      /* device dependent entry points */
  2558. 18623 int device;             /* device to partition */
  2559. 18624 int style;              /* partitioning style: floppy, primary, sub. */
  2560. 18625 {
  2561. 18626 /* This routine is called on first open to initialize the partition tables
  2562. 18627  * of a device.  It makes sure that each partition falls safely within the
  2563. 18628  * device's limits.  Depending on the partition style we are either making
  2564. 18629  * floppy partitions, primary partitions or subpartitions.  Only primary
  2565. 18630  * partitions are sorted, because they are shared with other operating
  2566. 18631  * systems that expect this.
  2567. 18632  */
  2568. 18633   struct part_entry table[NR_PARTITIONS], *pe;
  2569. 18634   int disk, par;
  2570. 18635   struct device *dv;
  2571. 18636   unsigned long base, limit, part_limit;
  2572. 18637
  2573. 18638   /* Get the geometry of the device to partition */
  2574. 18639   if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV || dv->dv_size == 0) return;
  2575. 18640   base = dv->dv_base >> SECTOR_SHIFT;
  2576. 18641   limit = base + (dv->dv_size >> SECTOR_SHIFT);
  2577. 18642
  2578. 18643   /* Read the partition table for the device. */
  2579. 18644   if (!get_part_table(dp, device, 0L, table)) return;
  2580. 18645
  2581. 18646   /* Compute the device number of the first partition. */
  2582. 18647   switch (style) {
  2583. 18648   case P_FLOPPY:
  2584. 18649         device += MINOR_fd0a;
  2585. 18650         break;
  2586. 18651   case P_PRIMARY:
  2587. 18652         sort(table);            /* sort a primary partition table */
  2588. 18653         device += 1;
  2589. 18654         break;
  2590. 18655   case P_SUB:
  2591. 18656         disk = device / DEV_PER_DRIVE;
  2592. 18657         par = device % DEV_PER_DRIVE - 1;
  2593. 18658         device = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
  2594. 18659   }
  2595. 18660
  2596. 18661   /* Find an array of devices. */
  2597. 18662   if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV) return;
  2598. 18663
  2599. 18664   /* Set the geometry of the partitions from the partition table. */
  2600. 18665   for (par = 0; par < NR_PARTITIONS; par++, dv++) {
  2601. 18666         /* Shrink the partition to fit within the device. */
  2602. 18667         pe = &table[par];
  2603. 18668         part_limit = pe->lowsec + pe->size;
  2604. 18669         if (part_limit < pe->lowsec) part_limit = limit;
  2605. 18670         if (part_limit > limit) part_limit = limit;
  2606. 18671         if (pe->lowsec < base) pe->lowsec = base;
  2607. 18672         if (part_limit < pe->lowsec) part_limit = pe->lowsec;
  2608. 18673
  2609. 18674         dv->dv_base = pe->lowsec << SECTOR_SHIFT;
  2610. 18675         dv->dv_size = (part_limit - pe->lowsec) << SECTOR_SHIFT;
  2611. 18676
  2612. 18677         if (style == P_PRIMARY) {
  2613. 18678                 /* Each Minix primary partition can be subpartitioned. */
  2614. 18679                 if (pe->sysind == MINIX_PART)
  2615. 18680                         partition(dp, device + par, P_SUB);
  2616. 18681
  2617. 18682                 /* An extended partition has logical partitions. */
  2618. 18683                 if (pe->sysind == EXT_PART)
  2619. 18684                         extpartition(dp, device + par, pe->lowsec);
  2620. 18685         }
  2621. 18686   }
  2622. 18687 }
  2623. 18690 /*============================================================================*
  2624. 18691  *                              extpartition                                  *
  2625. 18692  *============================================================================*/
  2626. 18693 PRIVATE void extpartition(dp, extdev, extbase)
  2627. 18694 struct driver *dp;      /* device dependent entry points */
  2628. 18695 int extdev;             /* extended partition to scan */
  2629. 18696 unsigned long extbase;  /* sector offset of the base extended partition */
  2630. 18697 {
  2631. 18698 /* Extended partitions cannot be ignored alas, because people like to move
  2632. 18699  * files to and from DOS partitions.  Avoid reading this code, it's no fun.
  2633. 18700  */
  2634. 18701   struct part_entry table[NR_PARTITIONS], *pe;
  2635. 18702   int subdev, disk, par;
  2636. 18703   struct device *dv;
  2637. 18704   unsigned long offset, nextoffset;
  2638. 18705
  2639. 18706   disk = extdev / DEV_PER_DRIVE;
  2640. 18707   par = extdev % DEV_PER_DRIVE - 1;
  2641. 18708   subdev = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
  2642. 18709
  2643. 18710   offset = 0;
  2644. 18711   do {
  2645. 18712         if (!get_part_table(dp, extdev, offset, table)) return;
  2646. 18713         sort(table);
  2647. 18714
  2648. 18715         /* The table should contain one logical partition and optionally
  2649. 18716          * another extended partition.  (It's a linked list.)
  2650. 18717          */
  2651. 18718         nextoffset = 0;
  2652. 18719         for (par = 0; par < NR_PARTITIONS; par++) {
  2653. 18720                 pe = &table[par];
  2654. 18721                 if (pe->sysind == EXT_PART) {
  2655. 18722                         nextoffset = pe->lowsec;
  2656. 18723                 } else
  2657. 18724                 if (pe->sysind != NO_PART) {
  2658. 18725                         if ((dv = (*dp->dr_prepare)(subdev)) == NIL_DEV) return;
  2659. 18726
  2660. 18727                         dv->dv_base = (extbase + offset
  2661. 18728                                         + pe->lowsec) << SECTOR_SHIFT;
  2662. 18729                         dv->dv_size = pe->size << SECTOR_SHIFT;
  2663. 18730
  2664. 18731                         /* Out of devices? */
  2665. 18732                         if (++subdev % NR_PARTITIONS == 0) return;
  2666. 18733                 }
  2667. 18734         }
  2668. 18735   } while ((offset = nextoffset) != 0);
  2669. 18736 }
  2670. 18739 /*============================================================================*
  2671. 18740  *                              get_part_table                                *
  2672. 18741  *============================================================================*/
  2673. 18742 PRIVATE int get_part_table(dp, device, offset, table)
  2674. 18743 struct driver *dp;
  2675. 18744 int device;
  2676. 18745 unsigned long offset;           /* sector offset to the table */
  2677. 18746 struct part_entry *table;       /* four entries */
  2678. 18747 {
  2679. 18748 /* Read the partition table for the device, return true iff there were no
  2680. 18749  * errors.
  2681. 18750  */
  2682. 18751   message mess;
  2683. 18752
  2684. 18753   mess.DEVICE = device;
  2685. 18754   mess.POSITION = offset << SECTOR_SHIFT;
  2686. 18755   mess.COUNT = SECTOR_SIZE;
  2687. 18756   mess.ADDRESS = (char *) tmp_buf;
  2688. 18757   mess.PROC_NR = proc_number(proc_ptr);
  2689. 18758   mess.m_type = DEV_READ;
  2690. 18759
  2691. 18760   if (do_rdwt(dp, &mess) != SECTOR_SIZE) {
  2692. 18761         printf("%s: can't read partition tablen", (*dp->dr_name)());
  2693. 18762         return 0;
  2694. 18763   }
  2695. 18764   if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) {
  2696. 18765         /* Invalid partition table. */
  2697. 18766         return 0;
  2698. 18767   }
  2699. 18768   memcpy(table, (tmp_buf + PART_TABLE_OFF), NR_PARTITIONS * sizeof(table[0]));
  2700. 18769   return 1;
  2701. 18770 }
  2702. 18773 /*===========================================================================*
  2703. 18774  *                              sort                                         *
  2704. 18775  *===========================================================================*/
  2705. 18776 PRIVATE void sort(table)
  2706. 18777 struct part_entry *table;
  2707. 18778 {
  2708. 18779 /* Sort a partition table. */
  2709. 18780   struct part_entry *pe, tmp;
  2710. 18781   int n = NR_PARTITIONS;
  2711. 18782
  2712. 18783   do {
  2713. 18784         for (pe = table; pe < table + NR_PARTITIONS-1; pe++) {
  2714. 18785                 if (pe[0].sysind == NO_PART
  2715. 18786                         || (pe[0].lowsec > pe[1].lowsec
  2716. 18787                                         && pe[1].sysind != NO_PART)) {
  2717. 18788                         tmp = pe[0]; pe[0] = pe[1]; pe[1] = tmp;
  2718. 18789                 }
  2719. 18790         }
  2720. 18791   } while (--n > 0);
  2721. 18792 }
  2722. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2723. src/kernel/esdi_wini.c    
  2724. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2725. 18800 /*     device dependent part of a hard disk driver for ibm ps/2 esdi adapter
  2726. 18801  *
  2727. 18802  *     written by doug burks, based on other minix wini drivers.
  2728. 18803  *     some additions by art roberts
  2729. 18804  *
  2730. 18805  *     references:
  2731. 18806  *        ibm personal system/2 hardware technical reference  (1988)
  2732. 18807  *        ibm 60/120mb fixed disk drive technical reference  (1988)
  2733. 18808  *
  2734. 18809  *     caveats:
  2735. 18810  *       * this driver has been reported to work on ibm ps/2 models 50 and
  2736. 18811  *         70 with ibm's 60/120mb hard disks.
  2737. 18812  *       * for a true esdi adapter, changes will have to be made, but this
  2738. 18813  *         certainly serves as a good start.
  2739. 18814  *       * no timeouts are implemented, so this driver could hang under
  2740. 18815  *         adverse conditions.
  2741. 18816  *       * the error processing has not been tested.  my disk works too well.
  2742. 18817  *
  2743. 18818  * The file contains one entry point:
  2744. 18819  *
  2745. 18820  *   esdi_winchester_task:      main entry when system is brought up
  2746. 18821  *
  2747. 18822  *
  2748. 18823  * Changes:
  2749. 18824  *       3 May 1992 by Kees J. Bot: device dependent/independent split.
  2750. 18825  */
  2751. 18826 #include "kernel.h"
  2752. 18827 #include "driver.h"
  2753. 18828 #include "drvlib.h"
  2754. 18829
  2755. 18830 #if ENABLE_ESDI_WINI
  2756. 18831
  2757. 18832 /* If the DMA buffer is large enough then use it always. */
  2758. 18833 #define USE_BUF         (DMA_BUF_SIZE > BLOCK_SIZE)