static unsigned char mca_pc_read_pos(struct mca_device *mca_dev, int reg) { unsigned char byte; unsigned long flags; if (reg < 0 || reg >= 8) return 0; spin_lock_irqsave(&mca_lock, flags); if (mca_dev->pos_register) { /* Disable adapter setup, enable motherboard setup */ outb_p(0, MCA_ADAPTER_SETUP_REG); outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); } else { /* Make sure motherboard setup is off */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* Read the appropriate register */ outb_p(0x8|(mca_dev->slot & 0xf), MCA_ADAPTER_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0, MCA_ADAPTER_SETUP_REG); } spin_unlock_irqrestore(&mca_lock, flags); mca_dev->pos[reg] = byte; return byte; }
static unsigned char mca_pc_read_pos(struct mca_device *mca_dev, int reg) { unsigned char byte; unsigned long flags; if (reg < 0 || reg >= 8) return 0; spin_lock_irqsave(&mca_lock, flags); if (mca_dev->pos_register) { outb_p(0, MCA_ADAPTER_SETUP_REG); outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); } else { outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); outb_p(0x8|(mca_dev->slot & 0xf), MCA_ADAPTER_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0, MCA_ADAPTER_SETUP_REG); } spin_unlock_irqrestore(&mca_lock, flags); mca_dev->pos[reg] = byte; return byte; }
u_int8_t mca_pos_get (device_t dev, u_int8_t reg) { u_int8_t slot = mca_get_slot(dev); u_int8_t data = 0; if ((slot > MCA_MAX_ADAPTERS) || (reg > MCA_POS7)) return (0); /* Disable motherboard setup */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); switch (slot) { case MCA_MB_SCSI_SLOT: /* Disable adapter setup */ outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); /* Select motherboard video setup regs */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_SCSI); /* read the register */ data = inb(MCA_POS_REG(reg)); /* Disable motherboard setup */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); break; case MCA_MB_VIDEO_SLOT: /* Disable adapter setup */ outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); /* Select motherboard scsi setup regs */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_VIDEO); /* read the register */ data = inb(MCA_POS_REG(reg)); /* Disable motherboard setup */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); break; default: /* Select adapter setup regs */ outb(MCA_ADAP_SETUP_REG, ((slot & 0x0f) | MCA_ADAP_SET)); /* read the register */ data = inb(MCA_POS_REG(reg)); /* Disable adapter setup */ outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); break; } return (data); }
unsigned char mca_read_pos( int slot, int reg ) { unsigned int byte = 0; unsigned long flags; if( slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0 ) return 0; if( reg < 0 || reg >= 8 ) return 0; save_flags( flags ); cli(); /* make sure motherboard setup is off */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* read in the appropriate register */ if( slot == MCA_INTEGSCSI && mca_info->which_scsi ) { /* disable adapter setup, enable motherboard setup */ outb_p(0, MCA_ADAPTER_SETUP_REG); outb_p(mca_info->which_scsi, MCA_MOTHERBOARD_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); } else if( slot == MCA_INTEGVIDEO ) { /* disable adapter setup, enable motherboard setup */ outb_p(0, MCA_ADAPTER_SETUP_REG); outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); } else if( slot < MCA_MAX_SLOT_NR ) { /* make sure motherboard setup is off */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* read the appropriate register */ outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG); byte = inb_p(MCA_POS_REG(reg)); outb_p(0, MCA_ADAPTER_SETUP_REG); } /* make sure the stored values are consistent, while we're here */ mca_info->slot[slot].pos[reg] = byte; restore_flags( flags ); return byte; } /* mca_read_pos() */
static void mca_pc_write_pos(struct mca_device *mca_dev, int reg, unsigned char byte) { unsigned long flags; if (reg < 0 || reg >= 8) return; spin_lock_irqsave(&mca_lock, flags); /* Make sure motherboard setup is off */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* Read in the appropriate register */ outb_p(0x8|(mca_dev->slot&0xf), MCA_ADAPTER_SETUP_REG); outb_p(byte, MCA_POS_REG(reg)); outb_p(0, MCA_ADAPTER_SETUP_REG); spin_unlock_irqrestore(&mca_lock, flags); /* Update the global register list, while we have the byte */ mca_dev->pos[reg] = byte; }
/* Not supposed to use this function! */ void mca_pos_set (device_t dev, u_int8_t reg, u_int8_t data) { struct mca_device * m_dev = device_get_ivars(dev); u_int8_t slot = mca_get_slot(dev); if ((slot > MCA_MAX_ADAPTERS) || (reg > MCA_POS7)) return; /* Disable motherboard setup */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); /* Select adapter setup regs */ outb(MCA_ADAP_SETUP_REG, ((slot & 0x0f) | MCA_ADAP_SET)); /* Write the register */ outb(MCA_POS_REG(reg), data); /* Disable adapter setup */ outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); /* Update the IVAR copy */ m_dev->pos[reg] = data; return; }
void mca_write_pos( int slot, int reg, unsigned char byte ) { unsigned long flags; if( slot < 0 || slot >= MCA_MAX_SLOT_NR ) return; if( reg < 0 || reg >= 8 ) return; if (mca_info == 0 ) return; save_flags( flags ); cli(); /* make sure motherboard setup is off */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* read in the appropriate register */ outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG); outb_p( byte, MCA_POS_REG(reg) ); outb_p(0, MCA_ADAPTER_SETUP_REG); restore_flags( flags ); /* update the global register list, while we have the byte */ mca_info->slot[slot].pos[reg] = byte; } /* mca_write_pos() */
static void mca_pc_write_pos(struct mca_device *mca_dev, int reg, unsigned char byte) { unsigned long flags; if (reg < 0 || reg >= 8) return; spin_lock_irqsave(&mca_lock, flags); outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); outb_p(0x8|(mca_dev->slot&0xf), MCA_ADAPTER_SETUP_REG); outb_p(byte, MCA_POS_REG(reg)); outb_p(0, MCA_ADAPTER_SETUP_REG); spin_unlock_irqrestore(&mca_lock, flags); mca_dev->pos[reg] = byte; }
void mca_conf_write(mca_chipset_tag_t mc, int slot, int reg, int data) { slot&=7; /* slot must be in range 0-7 */ outb(MCA_MB_SETUP_REG, 0xff); /* ensure m/board setup is disabled */ outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET); outb(MCA_POS_REG(reg), data); outb(MCA_ADAP_SETUP_REG, 0); }
int mca_conf_read(mca_chipset_tag_t mc, int slot, int reg) { int data; slot &= 7; /* slot must be in range 0-7 */ outb(MCA_MB_SETUP_REG, 0xff); /* ensure m/board setup is disabled */ outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET); data = inb(MCA_POS_REG(reg)); outb(MCA_ADAP_SETUP_REG, 0); return data; }
/* * Handle a NMI. * return true to panic system, false to ignore. */ int mca_nmi(void) { /* * PS/2 MCA devices can generate NMIs - we can find out which * slot generated it from the POS registers. */ int slot, mcanmi=0; /* if there is no MCA bus, call x86_nmi() */ if (!MCA_system) goto out; /* ensure motherboard setup is disabled */ outb(MCA_MB_SETUP_REG, 0xff); /* find if an MCA slot has the CHCK bit asserted (low) in POS 5 */ for(slot=0; slot<MCA_MAX_SLOTS; slot++) { outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET); if ((inb(MCA_POS_REG(5)) & MCA_POS5_CHCK) == 0) { mcanmi = 1; /* find if CHCK status is available in POS 6/7 */ if((inb(MCA_POS_REG(5)) & MCA_POS5_CHCK_STAT) == 0) log(LOG_CRIT, "MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n", slot+1, inb(MCA_POS_REG(6)), inb(MCA_POS_REG(7))); else log(LOG_CRIT, "MCA NMI: slot %d\n", slot+1); } } outb(MCA_ADAP_SETUP_REG, 0); out: if (!mcanmi) { /* no CHCK bits asserted, assume ISA NMI */ return (x86_nmi()); } else return(0); }
int mca_bus_nmi (void) { int slot; int retval = 0; int pos5 = 0; /* Disable motherboard setup */ outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); /* For each slot */ for (slot = 0; slot < MCA_MAX_SLOTS; slot++) { /* Select the slot */ outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET); pos5 = inb(MCA_POS_REG(MCA_POS5)); /* If Adapter Check is low */ if ((pos5 & MCA_POS5_CHCK) == 0) { retval++; /* If Adapter Check Status is available */ if ((pos5 & MCA_POS5_CHCK_STAT) == 0) { printf("MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n", slot+1, inb( MCA_POS_REG(MCA_POS6) ), inb( MCA_POS_REG(MCA_POS7) )); } else { printf("MCA NMI: slot %d\n", slot+1); } } /* Disable adapter setup */ outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); } return (retval); }
static int mca_read_and_store_pos(unsigned char *pos) { int j; int found = 0; for (j = 0; j < 8; j++) { pos[j] = inb_p(MCA_POS_REG(j)); if (pos[j] != 0xff) { found = 1; } } return found; }
/** * mca_read_and_store_pos - read the POS registers into a memory buffer * @pos: a char pointer to 8 bytes, contains the POS register value on * successful return * * Returns 1 if a card actually exists (i.e. the pos isn't * all 0xff) or 0 otherwise */ static int mca_read_and_store_pos(unsigned char *pos) { int j; int found = 0; for(j=0; j<8; j++) { if((pos[j] = inb_p(MCA_POS_REG(j))) != 0xff) { /* 0xff all across means no device. 0x00 means * something's broken, but a device is * probably there. However, if you get 0x00 * from a motherboard register it won't matter * what we find. For the record, on the * 57SLC, the integrated SCSI adapter has * 0xffff for the adapter ID, but nonzero for * other registers. */ found = 1; } } return found; }
__initfunc(void mca_init(void)) { unsigned int i, j; unsigned long flags; /* WARNING: Be careful when making changes here. Putting an adapter * and the motherboard simultaneously into setup mode may result in * damage to chips (according to The Indispensible PC Hardware Book * by Hans-Peter Messmer). Also, we disable system interrupts (so * that we are not disturbed in the middle of this). */ /* Make sure the MCA bus is present */ if (!MCA_bus) return; printk( "Micro Channel bus detected.\n" ); save_flags( flags ); cli(); /* Allocate MCA_info structure (at address divisible by 8) */ mca_info = kmalloc(sizeof(struct MCA_info), GFP_ATOMIC); /* Make sure adapter setup is off */ outb_p(0, MCA_ADAPTER_SETUP_REG); /* Put motherboard into video setup mode, read integrated video * pos registers, and turn motherboard setup off. */ outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG); mca_info->slot[MCA_INTEGVIDEO].name[0] = 0; for (j=0; j<8; j++) { mca_info->slot[MCA_INTEGVIDEO].pos[j] = inb_p(MCA_POS_REG(j)); } mca_configure_adapter_status(MCA_INTEGVIDEO); /* Put motherboard into scsi setup mode, read integrated scsi * pos registers, and turn motherboard setup off. * * It seems there are two possible SCSI registers. Martin says that * for the 56,57, 0xf7 is the one, but fails on the 76. * Alfredo ([email protected]) says * 0xfd works on his machine. We'll try both of them. I figure it's * a good bet that only one could be valid at a time. This could * screw up though if one is used for something else on the other * machine. */ outb_p(0xf7, MCA_MOTHERBOARD_SETUP_REG); mca_info->slot[MCA_INTEGSCSI].name[0] = 0; for (j=0; j<8; j++) { if( (mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff ) { /* 0xff all across means no device. 0x00 means something's * broken, but a device is probably there. However, if you get * 0x00 from a motherboard register it won't matter what we * find. For the record, on the 57SLC, the integrated SCSI * adapter has 0xffff for the adapter ID, but nonzero for * other registers. */ mca_info->which_scsi = 0xf7; } } if( !mca_info->which_scsi ) { /* Didn't find it at 0xf7, try somewhere else... */ mca_info->which_scsi = 0xfd; outb_p(0xfd, MCA_MOTHERBOARD_SETUP_REG); for (j=0; j<8; j++) mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j)); } mca_configure_adapter_status(MCA_INTEGSCSI); /* turn off motherboard setup */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* Now loop over MCA slots: put each adapter into setup mode, and * read its pos registers. Then put adapter setup off. */ for (i=0; i<MCA_MAX_SLOT_NR; i++) { outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG); for (j=0; j<8; j++) { mca_info->slot[i].pos[j]=inb_p(MCA_POS_REG(j)); } mca_info->slot[i].name[0] = 0; mca_info->slot[i].driver_loaded = 0; mca_configure_adapter_status(i); } outb_p(0, MCA_ADAPTER_SETUP_REG); /* Enable interrupts and return memory start */ restore_flags( flags ); request_region(0x60,0x01,"system control port B (MCA)"); request_region(0x90,0x01,"arbitration (MCA)"); request_region(0x91,0x01,"card Select Feedback (MCA)"); request_region(0x92,0x01,"system Control port A (MCA)"); request_region(0x94,0x01,"system board setup (MCA)"); request_region(0x96,0x02,"POS (MCA)"); request_region(0x100,0x08,"POS (MCA)"); #ifdef CONFIG_PROC_FS mca_do_proc_init(); #endif }