]> Git Repo - binutils.git/blob - sim/mn10300/dv-mn103int.c
Automatic date update in version.in
[binutils.git] / sim / mn10300 / dv-mn103int.c
1 /*  This file is part of the program GDB, the GNU debugger.
2     
3     Copyright (C) 1998-2022 Free Software Foundation, Inc.
4     Contributed by Cygnus Solutions.
5     
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18     
19     */
20
21 /* This must come before any other includes.  */
22 #include "defs.h"
23
24 #include "sim-main.h"
25 #include "hw-main.h"
26 #include "sim-hw.h"
27
28 /* DEVICE
29
30    
31    mn103int - mn103002 interrupt controller
32
33    
34    DESCRIPTION
35
36    
37    Implements the mn103002 interrupt controller described in the
38    mn103002 user guide.
39
40
41    PROPERTIES
42    
43
44    reg = <icr-adr> <icr-siz> <iagr-adr> <iadr-siz> <extmd-adr> <extmd-siz>
45
46    Specify the address of the ICR (total of 30 registers), IAGR and
47    EXTMD registers (within the parent bus).
48
49    The reg property value `0x34000100 0x7C 0x34000200 0x8 0x3400280
50    0x8' locates the interrupt controller at the addresses specified in
51    the mn103002 interrupt controller user guide.
52
53
54    PORTS
55
56
57    nmi (output)
58
59    Non-maskable interrupt output port.  An event on this output ports
60    indicates a NMI request from the interrupt controller.  The value
61    attached to the event should be ignored.
62
63
64    level (output)
65
66    Maskable interrupt level output port.  An event on this output port
67    indicates a maskable interrupt request at the specified level.  The
68    event value defines the level being requested.
69
70    The interrupt controller will generate an event on this port
71    whenever there is a change to the internal state of the interrupt
72    controller.
73
74
75    ack (input)
76
77    Signal from processor indicating that a maskable interrupt has been
78    accepted and the interrupt controller should latch the IAGR with
79    value of the current highest priority interrupting group.
80
81    The event value is the interrupt level being accepted by the
82    processor.  It should be consistent with the most recent LEVEL sent
83    to the processor from the interrupt controller.
84
85
86    int[0..100] (input)
87
88    Level or edge triggered interrupt input port.  Each of the 30
89    groups (0..30) can have up to 4 (0..3) interrupt inputs.  The
90    interpretation of a port event/value is determined by the
91    configuration of the corresponding interrupt group.
92
93    For convenience, numerous aliases to these interrupt inputs are
94    provided.
95
96
97    BUGS
98
99
100    For edge triggered interrupts, the interrupt controller does not
101    differentiate between POSITIVE (rising) and NEGATIVE (falling)
102    edges.  Instead any input port event is considered to be an
103    interrupt trigger.
104
105    For level sensitive interrupts, the interrupt controller ignores
106    active HIGH/LOW settings and instead always interprets a nonzero
107    port value as an interrupt assertion and a zero port value as a
108    negation.
109
110    */
111
112
113 /* The interrupt groups - numbered according to mn103002 convention */
114
115 enum mn103int_trigger {
116   ACTIVE_LOW,
117   ACTIVE_HIGH,
118   POSITIVE_EDGE,
119   NEGATIVE_EDGE,
120 };
121
122 enum mn103int_type {
123   NMI_GROUP,
124   LEVEL_GROUP,
125 };
126
127 struct mn103int_group {
128   int gid;
129   int level;
130   unsigned enable;
131   unsigned request;
132   unsigned input;
133   enum mn103int_trigger trigger;
134   enum mn103int_type type;
135 };
136
137 enum {
138   FIRST_NMI_GROUP = 0,
139   LAST_NMI_GROUP = 1,
140   FIRST_LEVEL_GROUP = 2,
141   LAST_LEVEL_GROUP = 30,
142   NR_GROUPS,
143 };
144
145 enum {
146   LOWEST_LEVEL = 7,
147 };
148
149 /* The interrupt controller register address blocks */
150
151 struct mn103int_block {
152   unsigned_word base;
153   unsigned_word bound;
154 };
155
156 enum { ICR_BLOCK, IAGR_BLOCK, EXTMD_BLOCK, NR_BLOCKS };
157
158
159 struct mn103int {
160   struct mn103int_block block[NR_BLOCKS];
161   struct mn103int_group group[NR_GROUPS];
162   unsigned interrupt_accepted_group;
163 };
164
165
166
167 /* output port ID's */ 
168
169 enum {
170   NMI_PORT,
171   LEVEL_PORT,
172 };
173
174
175 /* input port ID's */
176
177 enum {
178   G0_PORT = 0,
179   G1_PORT = 4,
180   G2_PORT = 8,
181   G3_PORT = 12,
182   G4_PORT = 16,
183   G5_PORT = 20,
184   G6_PORT = 24,
185   G7_PORT = 28,
186   G8_PORT = 32,
187   G9_PORT = 36,
188   G10_PORT = 40,
189   G11_PORT = 44,
190   G12_PORT = 48,
191   G13_PORT = 52,
192   G14_PORT = 56,
193   G15_PORT = 60,
194   G16_PORT = 64,
195   G17_PORT = 68,
196   G18_PORT = 72,
197   G19_PORT = 76,
198   G20_PORT = 80,
199   G21_PORT = 84,
200   G22_PORT = 88,
201   G23_PORT = 92,
202   IRQ0_PORT = G23_PORT,
203   G24_PORT = 96,
204   G25_PORT = 100,
205   G26_PORT = 104,
206   G27_PORT = 108,
207   IRQ4_PORT = G27_PORT,
208   G28_PORT = 112,
209   G29_PORT = 116,
210   G30_PORT = 120,
211   NR_G_PORTS = 124,
212   ACK_PORT,
213 };
214
215 static const struct hw_port_descriptor mn103int_ports[] = {
216
217   /* interrupt outputs */
218
219   { "nmi", NMI_PORT, 0, output_port, },
220   { "level", LEVEL_PORT, 0, output_port, },
221
222   /* interrupt ack (latch) input from cpu */
223
224   { "ack", ACK_PORT, 0, input_port, },
225
226   /* interrupt inputs (as names) */
227
228   { "nmirq", G0_PORT + 0, 0, input_port, },
229   { "watchdog", G0_PORT + 1, 0, input_port, },
230   { "syserr", G0_PORT + 2, 0, input_port, },
231
232   { "timer-0-underflow", G2_PORT, 0, input_port, },
233   { "timer-1-underflow", G3_PORT, 0, input_port, },
234   { "timer-2-underflow", G4_PORT, 0, input_port, },
235   { "timer-3-underflow", G5_PORT, 0, input_port, },
236   { "timer-4-underflow", G6_PORT, 0, input_port, },
237   { "timer-5-underflow", G7_PORT, 0, input_port, },
238   { "timer-6-underflow", G8_PORT, 0, input_port, },
239
240   { "timer-6-compare-a", G9_PORT, 0, input_port, },
241   { "timer-6-compare-b", G10_PORT, 0, input_port, },
242
243   { "dma-0-end", G12_PORT, 0, input_port, },
244   { "dma-1-end", G13_PORT, 0, input_port, },
245   { "dma-2-end", G14_PORT, 0, input_port, },
246   { "dma-3-end", G15_PORT, 0, input_port, },
247
248   { "serial-0-receive",  G16_PORT, 0, input_port, },
249   { "serial-0-transmit", G17_PORT, 0, input_port, },
250
251   { "serial-1-receive",  G18_PORT, 0, input_port, },
252   { "serial-1-transmit", G19_PORT, 0, input_port, },
253
254   { "serial-2-receive",  G20_PORT, 0, input_port, },
255   { "serial-2-transmit", G21_PORT, 0, input_port, },
256
257   { "irq-0", G23_PORT, 0, input_port, },
258   { "irq-1", G24_PORT, 0, input_port, },
259   { "irq-2", G25_PORT, 0, input_port, },
260   { "irq-3", G26_PORT, 0, input_port, },
261   { "irq-4", G27_PORT, 0, input_port, },
262   { "irq-5", G28_PORT, 0, input_port, },
263   { "irq-6", G29_PORT, 0, input_port, },
264   { "irq-7", G30_PORT, 0, input_port, },
265
266   /* interrupt inputs (as generic numbers) */
267
268   { "int", 0, NR_G_PORTS, input_port, },
269
270   { NULL, },
271 };
272
273
274 /* Macros for extracting/restoring the various register bits */
275
276 #define EXTRACT_ID(X) (LSEXTRACTED8 ((X), 3, 0))
277 #define INSERT_ID(X) (LSINSERTED8 ((X), 3, 0))
278
279 #define EXTRACT_IR(X) (LSEXTRACTED8 ((X), 7, 4))
280 #define INSERT_IR(X) (LSINSERTED8 ((X), 7, 4))
281
282 #define EXTRACT_IE(X) (LSEXTRACTED8 ((X), 3, 0))
283 #define INSERT_IE(X) (LSINSERTED8 ((X), 3, 0))
284
285 #define EXTRACT_LV(X) (LSEXTRACTED8 ((X), 6, 4))
286 #define INSERT_LV(X) (LSINSERTED8 ((X), 6, 4))
287
288
289
290 /* Finish off the partially created hw device.  Attach our local
291    callbacks.  Wire up our port names etc */
292
293 static hw_io_read_buffer_method mn103int_io_read_buffer;
294 static hw_io_write_buffer_method mn103int_io_write_buffer;
295 static hw_port_event_method mn103int_port_event;
296 static hw_ioctl_method mn103int_ioctl;
297
298
299
300 static void
301 attach_mn103int_regs (struct hw *me,
302                       struct mn103int *controller)
303 {
304   int i;
305   if (hw_find_property (me, "reg") == NULL)
306     hw_abort (me, "Missing \"reg\" property");
307   for (i = 0; i < NR_BLOCKS; i++)
308     {
309       unsigned_word attach_address;
310       int attach_space;
311       unsigned attach_size;
312       reg_property_spec reg;
313       if (!hw_find_reg_array_property (me, "reg", i, &reg))
314         hw_abort (me, "\"reg\" property must contain three addr/size entries");
315       hw_unit_address_to_attach_address (hw_parent (me),
316                                          &reg.address,
317                                          &attach_space,
318                                          &attach_address,
319                                          me);
320       controller->block[i].base = attach_address;
321       hw_unit_size_to_attach_size (hw_parent (me),
322                                    &reg.size,
323                                    &attach_size, me);
324       controller->block[i].bound = attach_address + (attach_size - 1);
325       hw_attach_address (hw_parent (me),
326                          0,
327                          attach_space, attach_address, attach_size,
328                          me);
329     }
330 }
331
332 static void
333 mn103int_finish (struct hw *me)
334 {
335   int gid;
336   struct mn103int *controller;
337
338   controller = HW_ZALLOC (me, struct mn103int);
339   set_hw_data (me, controller);
340   set_hw_io_read_buffer (me, mn103int_io_read_buffer);
341   set_hw_io_write_buffer (me, mn103int_io_write_buffer);
342   set_hw_ports (me, mn103int_ports);
343   set_hw_port_event (me, mn103int_port_event);
344   me->to_ioctl = mn103int_ioctl;
345
346   /* Attach ourself to our parent bus */
347   attach_mn103int_regs (me, controller);
348
349   /* Initialize all the groups according to their default configuration */
350   for (gid = 0; gid < NR_GROUPS; gid++)
351     {
352       struct mn103int_group *group = &controller->group[gid];
353       group->trigger = NEGATIVE_EDGE;
354       group->gid = gid;
355       if (FIRST_NMI_GROUP <= gid && gid <= LAST_NMI_GROUP)
356         {
357           group->enable = 0xf;
358           group->type = NMI_GROUP;
359         }
360       else if (FIRST_LEVEL_GROUP <= gid && gid <= LAST_LEVEL_GROUP)
361         {
362           group->enable = 0x0;
363           group->type = LEVEL_GROUP;
364         }
365       else
366         hw_abort (me, "internal error - unknown group id");
367     }
368 }
369
370
371
372 /* Perform the nasty work of figuring out which of the interrupt
373    groups should have its interrupt delivered. */
374
375 static int
376 find_highest_interrupt_group (struct hw *me,
377                               struct mn103int *controller)
378 {
379   int gid;
380   int selected;
381
382   /* FIRST_NMI_GROUP (group zero) is used as a special default value
383      when searching for an interrupt group.*/
384   selected = FIRST_NMI_GROUP; 
385   controller->group[FIRST_NMI_GROUP].level = 7;
386   
387   for (gid = FIRST_LEVEL_GROUP; gid <= LAST_LEVEL_GROUP; gid++)
388     {
389       struct mn103int_group *group = &controller->group[gid];
390       if ((group->request & group->enable) != 0)
391         {
392           /* Remember, lower level, higher priority.  */
393           if (group->level < controller->group[selected].level)
394             {
395               selected = gid;
396             }
397         }
398     }
399   return selected;
400 }
401
402
403 /* Notify the processor of an interrupt level update */
404
405 static void
406 push_interrupt_level (struct hw *me,
407                       struct mn103int *controller)
408 {
409   int selected = find_highest_interrupt_group (me, controller);
410   int level = controller->group[selected].level;
411   HW_TRACE ((me, "port-out - selected=%d level=%d", selected, level));
412   hw_port_event (me, LEVEL_PORT, level);
413 }
414
415
416 /* An event arrives on an interrupt port */
417
418 static void
419 mn103int_port_event (struct hw *me,
420                      int my_port,
421                      struct hw *source,
422                      int source_port,
423                      int level)
424 {
425   struct mn103int *controller = hw_data (me);
426
427   switch (my_port)
428     {
429
430     case ACK_PORT:
431       {
432         int selected = find_highest_interrupt_group (me, controller);
433         if (controller->group[selected].level != level)
434           hw_abort (me, "botched level synchronisation");
435         controller->interrupt_accepted_group = selected;        
436         HW_TRACE ((me, "port-event port=ack level=%d - selected=%d",
437                    level, selected));
438         break;
439       }
440
441     default:
442       {
443         int gid;
444         int iid;
445         struct mn103int_group *group;
446         unsigned interrupt;
447         if (my_port > NR_G_PORTS)
448           hw_abort (me, "Event on unknown port %d", my_port);
449
450         /* map the port onto an interrupt group */
451         gid = (my_port % NR_G_PORTS) / 4;
452         group = &controller->group[gid];
453         iid = (my_port % 4);
454         interrupt = 1 << iid;
455
456         /* update our cached input */
457         if (level)
458           group->input |= interrupt;
459         else
460           group->input &= ~interrupt;
461
462         /* update the request bits */
463         switch (group->trigger)
464           {
465           case ACTIVE_LOW:
466           case ACTIVE_HIGH:
467             if (level)
468               group->request |= interrupt;
469             break;
470           case NEGATIVE_EDGE:
471           case POSITIVE_EDGE:
472             group->request |= interrupt;
473           }
474
475         /* force a corresponding output */
476         switch (group->type)
477           {
478
479           case NMI_GROUP:
480             {
481               /* for NMI's the event is the trigger */
482               HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - NMI",
483                          my_port, gid, iid));
484               if ((group->request & group->enable) != 0)
485                 {
486                   HW_TRACE ((me, "port-out NMI"));
487                   hw_port_event (me, NMI_PORT, 1);
488                 }
489               break;
490             }
491               
492           case LEVEL_GROUP:
493             {
494               /* if an interrupt is now pending */
495               HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - INT",
496                          my_port, gid, iid));
497               push_interrupt_level (me, controller);
498               break;
499             }
500           }
501         break;
502       }
503
504     }
505 }
506
507 /* Read/write to to an ICR (group control register) */
508
509 static struct mn103int_group *
510 decode_group (struct hw *me,
511               struct mn103int *controller,
512               unsigned_word base,
513               unsigned_word *offset)
514 {
515   int gid = (base / 4) % NR_GROUPS;
516   *offset = (base % 4);
517   return &controller->group[gid];
518 }
519
520 static uint8_t
521 read_icr (struct hw *me,
522           struct mn103int *controller,
523           unsigned_word base)
524 {
525   unsigned_word offset;
526   struct mn103int_group *group = decode_group (me, controller, base, &offset);
527   uint8_t val = 0;
528   switch (group->type)
529     {
530
531     case NMI_GROUP:
532       switch (offset)
533         {
534         case 0:
535           val = INSERT_ID (group->request);
536           HW_TRACE ((me, "read-icr group=%d:0 nmi 0x%02x",
537                      group->gid, val));
538           break;
539         default:
540           break;
541         }
542       break;
543
544     case LEVEL_GROUP:
545       switch (offset)
546         {
547         case 0:
548           val = (INSERT_IR (group->request)
549                  | INSERT_ID (group->request & group->enable));
550           HW_TRACE ((me, "read-icr group=%d:0 level 0x%02x",
551                      group->gid, val));
552           break;
553         case 1:
554           val = (INSERT_LV (group->level)
555                  | INSERT_IE (group->enable));
556           HW_TRACE ((me, "read-icr level-%d:1 level 0x%02x",
557                      group->gid, val));
558           break;
559         }
560       break;
561
562     default:
563       break;
564
565     }
566
567   return val;
568 }
569
570 static void
571 write_icr (struct hw *me,
572            struct mn103int *controller,
573            unsigned_word base,
574            uint8_t val)
575 {
576   unsigned_word offset;
577   struct mn103int_group *group = decode_group (me, controller, base, &offset);
578   switch (group->type)
579     {
580
581     case NMI_GROUP:
582       switch (offset)
583         {
584         case 0:
585           HW_TRACE ((me, "write-icr group=%d:0 nmi 0x%02x",
586                      group->gid, val));
587           group->request &= ~EXTRACT_ID (val);
588           break;
589           /* Special backdoor access to SYSEF flag from CPU.  See
590              interp.c:program_interrupt(). */
591         case 3:
592           HW_TRACE ((me, "write-icr-special group=%d:0 nmi 0x%02x",
593                      group->gid, val));
594           group->request |= EXTRACT_ID (val);
595         default:
596           break;
597         }
598       break;
599
600     case LEVEL_GROUP:
601       switch (offset)
602         {
603         case 0: /* request/detect */
604           /* Clear any ID bits and then set them according to IR */
605           HW_TRACE ((me, "write-icr group=%d:0 level 0x%02x %x:%x:%x",
606                      group->gid, val,
607                      group->request, EXTRACT_IR (val), EXTRACT_ID (val)));
608           group->request =
609             ((EXTRACT_IR (val) & EXTRACT_ID (val))
610              | (EXTRACT_IR (val) & group->request)
611              | (~EXTRACT_IR (val) & ~EXTRACT_ID (val) & group->request));
612           break;
613         case 1: /* level/enable */
614           HW_TRACE ((me, "write-icr group=%d:1 level 0x%02x",
615                      group->gid, val));
616           group->level = EXTRACT_LV (val);
617           group->enable = EXTRACT_IE (val);
618           break;
619         default:
620           /* ignore */
621           break;
622         }
623       push_interrupt_level (me, controller);
624       break;
625
626     default:
627       break;
628
629     }
630 }
631
632
633 /* Read the IAGR (Interrupt accepted group register) */
634
635 static uint8_t
636 read_iagr (struct hw *me,
637            struct mn103int *controller,
638            unsigned_word offset)
639 {
640   uint8_t val;
641   switch (offset)
642     {
643     case 0:
644       {
645         if (!(controller->group[controller->interrupt_accepted_group].request
646               & controller->group[controller->interrupt_accepted_group].enable))
647           {
648             /* oops, lost the request */
649             val = 0;
650             HW_TRACE ((me, "read-iagr:0 lost-0"));
651           }
652         else
653           {
654             val = (controller->interrupt_accepted_group << 2);
655             HW_TRACE ((me, "read-iagr:0 %d", (int) val));
656           }
657         break;
658       }
659     case 1:
660       val = 0;
661       HW_TRACE ((me, "read-iagr:1 %d", (int) val));
662       break;
663     default:
664       val = 0;
665       HW_TRACE ((me, "read-iagr 0x%08lx bad offset", (long) offset));
666       break;
667     }
668   return val;
669 }
670
671
672 /* Reads/writes to the EXTMD (external interrupt trigger configuration
673    register) */
674
675 static struct mn103int_group *
676 external_group (struct mn103int *controller,
677                 unsigned_word offset)
678 {
679   switch (offset)
680     {
681     case 0:
682       return &controller->group[IRQ0_PORT/4];
683     case 1:
684       return &controller->group[IRQ4_PORT/4];
685     default:
686       return NULL;
687     }
688 }
689
690 static uint8_t
691 read_extmd (struct hw *me,
692             struct mn103int *controller,
693             unsigned_word offset)
694 {
695   int gid;
696   uint8_t val = 0;
697   struct mn103int_group *group = external_group (controller, offset);
698   if (group != NULL)
699     {
700       for (gid = 0; gid < 4; gid++)
701         {
702           val |= (group[gid].trigger << (gid * 2));
703         }
704     }
705   HW_TRACE ((me, "read-extmd 0x%02lx", (long) val));
706   return val;
707 }
708
709 static void
710 write_extmd (struct hw *me,
711              struct mn103int *controller,
712              unsigned_word offset,
713              uint8_t val)
714 {
715   int gid;
716   struct mn103int_group *group = external_group (controller, offset);
717   if (group != NULL)
718     {
719       for (gid = 0; gid < 4; gid++)
720         {
721           group[gid].trigger = (val >> (gid * 2)) & 0x3;
722           /* MAYBE: interrupts already pending? */
723         }
724     }
725   HW_TRACE ((me, "write-extmd 0x%02lx", (long) val));
726 }
727
728
729 /* generic read/write */
730
731 static int
732 decode_addr (struct hw *me,
733              struct mn103int *controller,
734              unsigned_word address,
735              unsigned_word *offset)
736 {
737   int i;
738   for (i = 0; i < NR_BLOCKS; i++)
739     {
740       if (address >= controller->block[i].base
741           && address <= controller->block[i].bound)
742         {
743           *offset = address - controller->block[i].base;
744           return i;
745         }
746     }
747   hw_abort (me, "bad address");
748   return -1;
749 }
750
751 static unsigned
752 mn103int_io_read_buffer (struct hw *me,
753                          void *dest,
754                          int space,
755                          unsigned_word base,
756                          unsigned nr_bytes)
757 {
758   struct mn103int *controller = hw_data (me);
759   uint8_t *buf = dest;
760   unsigned byte;
761   /* HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); */
762   for (byte = 0; byte < nr_bytes; byte++)
763     {
764       unsigned_word address = base + byte;
765       unsigned_word offset;
766       switch (decode_addr (me, controller, address, &offset))
767         {
768         case ICR_BLOCK:
769           buf[byte] = read_icr (me, controller, offset);
770           break;
771         case IAGR_BLOCK:
772           buf[byte] = read_iagr (me, controller, offset);
773           break;
774         case EXTMD_BLOCK:
775           buf[byte] = read_extmd (me, controller, offset);
776           break;
777         default:
778           hw_abort (me, "bad switch");
779         }
780     }
781   return nr_bytes;
782 }     
783
784 static unsigned
785 mn103int_io_write_buffer (struct hw *me,
786                           const void *source,
787                           int space,
788                           unsigned_word base,
789                           unsigned nr_bytes)
790 {
791   struct mn103int *controller = hw_data (me);
792   const uint8_t *buf = source;
793   unsigned byte;
794   /* HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); */
795   for (byte = 0; byte < nr_bytes; byte++)
796     {
797       unsigned_word address = base + byte;
798       unsigned_word offset;
799       switch (decode_addr (me, controller, address, &offset))
800         {
801         case ICR_BLOCK:
802           write_icr (me, controller, offset, buf[byte]);
803           break;
804         case IAGR_BLOCK:
805           /* not allowed */
806           break;
807         case EXTMD_BLOCK:
808           write_extmd (me, controller, offset, buf[byte]);
809           break;
810         default:
811           hw_abort (me, "bad switch");
812         }
813     }
814   return nr_bytes;
815 }     
816
817 static int
818 mn103int_ioctl(struct hw *me,
819                hw_ioctl_request request,
820                va_list ap)
821 {
822   struct mn103int *controller = (struct mn103int *)hw_data(me);
823   controller->group[0].request = EXTRACT_ID(4);
824   mn103int_port_event(me, 2 /* nmi_port(syserr) */, NULL, 0, 0);
825   return 0;
826 }
827
828
829 const struct hw_descriptor dv_mn103int_descriptor[] = {
830   { "mn103int", mn103int_finish, },
831   { NULL },
832 };
This page took 0.068966 seconds and 4 git commands to generate.