Main Page | Directories | File List | Globals

i8259a.c

Go to the documentation of this file.
00001 /*
00002  * kernel_drivers/adi_chips/i8259a.c
00003  *
00004  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  * 
00007  * Date:        2004/01
00008  * Author:      Lukasz Dembinski
00009  * Info:        i8259a.c core file
00010  * Contact:     mailto: <dembol@nasa.com.pl>
00011  *
00012  */
00013 
00014 #include <agnix/agnix.h>
00015 #include <agnix/adi/adi.h>
00016 #include <agnix/spinlock.h>
00017 #include <asm/types.h>
00018 #include <agnix/ioport.h>
00019 #include <agnix/memory.h>
00020 #include <agnix/irq.h>
00021 #include <agnix/console.h>
00022 
00023 #define I8259A_CASCADE_IRQ      2
00024 
00025 struct chip_pic_parm_s  i8259a_pic_parm;
00026 
00027 int i8259a_startup_irq(struct chip_s *chip, u8 irq)
00028 {
00029     return 0;
00030 }
00031 
00032 int i8259a_shutdown_irq(struct chip_s *chip, u8 irq)
00033 {
00034     return 0;
00035 }
00036 
00037 int i8259a_enable_irq(struct chip_s *chip, u8 irq)
00038 {
00039     CHIP_LOCK;
00040 
00041     pic_parm(chip)->irq_mask[0] &= ~(1 << irq);
00042     outb((pic_parm(chip)->irq_mask[0]) & 0xFF, INT_CNTRL_1 + 1);
00043     outb((pic_parm(chip)->irq_mask[0] >> 8) & 0xFF, INT_CNTRL_2 + 1);
00044 
00045     CHIP_UNLOCK;
00046 
00047     return 0;
00048 }
00049 
00050 int i8259a_disable_irq(struct chip_s *chip, u8 irq)
00051 {
00052     CHIP_LOCK;
00053 
00054     pic_parm(chip)->irq_mask[0] |= 1 << irq;
00055     outb((pic_parm(chip)->irq_mask[0]) & 0xFF, INT_CNTRL_1 + 1);
00056     outb((pic_parm(chip)->irq_mask[0] >> 8) & 0xFF, INT_CNTRL_2 + 1);
00057 
00058     CHIP_UNLOCK;
00059 
00060 
00061     return 0;
00062 }
00063 
00064 void i8259a_ack_irq(struct chip_s *chip, u8 irq)
00065 {
00066     CHIP_LOCK;
00067 
00068     if (irq <= 7)
00069         outb(0x60 + (irq & 0x07), INT_CNTRL_1);
00070     else
00071     if (irq <= 15) {
00072         outb(0x60 + (irq & 0x07), INT_CNTRL_2);
00073         outb(0x60 + I8259A_CASCADE_IRQ, INT_CNTRL_1);
00074     }
00075 
00076     CHIP_UNLOCK;
00077 }
00078 
00079 void i8259a_mask_irq(struct chip_s *chip, u8 irq)
00080 {
00081     CHIP_LOCK;
00082     CHIP_UNLOCK;
00083 }
00084 
00085 struct chip_pic_ops_s   i8259a_pic_ops = 
00086 {
00087     .startup_irq        = i8259a_startup_irq,
00088     .shutdown_irq       = i8259a_shutdown_irq,
00089     .enable_irq         = i8259a_enable_irq,
00090     .disable_irq        = i8259a_disable_irq,
00091     .ack_irq            = i8259a_ack_irq,
00092     .mask_irq           = i8259a_mask_irq
00093 };
00094 
00095 void i8259a_cascade_irq(u32 data)
00096 {
00097     printk("cascade irq\n");
00098 }
00099 
00100 struct irq_routine_s i8259a_cascade_irq_routine = {
00101     .proc               = i8259a_cascade_irq,
00102 };
00103 
00104 int i8259a_chip_cascade_init(struct chip_s *chip)
00105 {
00106     install_irq(I8259A_CASCADE_IRQ, &i8259a_cascade_irq_routine);
00107     
00108     return 0;
00109 }
00110 
00111 int i8259a_chip_init(struct chip_s *chip)
00112 {
00113     CHIP_LOCK;
00114 
00115     memset(pic_parm(chip)->irq_mask, 0xFF, PIC_MASK_BYTES);
00116 
00117     outb(0x11, INT_CNTRL_1);
00118     outb(0x20, INT_CNTRL_1 + 1);
00119     outb(0x04, INT_CNTRL_1 + 1);
00120     outb(0x01, INT_CNTRL_1 + 1);
00121     
00122     outb(0x11, INT_CNTRL_2);
00123     outb(0x28, INT_CNTRL_2 + 1);
00124     outb(0x02, INT_CNTRL_2 + 1);
00125     outb(0x01, INT_CNTRL_2 + 1);
00126     
00127     outb((u8)((pic_parm(chip)->irq_mask[0]) & 0xFF), INT_CNTRL_1 + 1);
00128     outb((u8)((pic_parm(chip)->irq_mask[0] >> 8) & 0xFF), INT_CNTRL_2 + 1);
00129 
00130     CHIP_UNLOCK;
00131 
00132     i8259a_chip_cascade_init(chip);
00133 
00134     return 0;
00135 }
00136 
00137 int i8259a_chip_release(struct chip_s *chip)
00138 {
00139     return 0;
00140 }
00141 
00142 struct chip_ops_s       i8259a_chip_ops = {
00143     .init               = i8259a_chip_init,
00144     .release            = i8259a_chip_release
00145 };
00146 
00147 struct chip_s           i8259a_chip = {
00148     .chip_name          = "i8259a",
00149     .chip_class         = CHIP_CLASS_PIC,
00150     .chip_vendor        = 0x8086,
00151     .chip_priority      = 90,
00152     .chip_ops           = &i8259a_chip_ops,
00153     .chip_pm_ops        = NULL,
00154     .internal_ops       = &i8259a_pic_ops,
00155     .internal_parm      = &i8259a_pic_parm
00156 };
00157 
00158 int __init i8259a_init(void)
00159 {
00160     adi_register_chip(&i8259a_chip);
00161 
00162     return 0;    
00163 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix