COMPLETE.T
上传用户:datang2001
上传日期:2007-02-01
资源大小:53269k
文件大小:2535k
源码类别:

操作系统开发

开发平台:

C/C++

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