__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 }
static int __init mca_init(void) { unsigned int i, j; struct mca_device *mca_dev; unsigned char pos[8]; short mca_builtin_scsi_ports[] = {0xf7, 0xfd, 0x00}; struct mca_bus *bus; /* * 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 Indispensable 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_system_init()) { printk(KERN_ERR "MCA bus system initialisation failed\n"); return -ENODEV; } if (!MCA_bus) return -ENODEV; printk(KERN_INFO "Micro Channel bus detected.\n"); /* All MCA systems have at least a primary bus */ bus = mca_attach_bus(MCA_PRIMARY_BUS); if (!bus) goto out_nomem; bus->default_dma_mask = 0xffffffffLL; bus->f.mca_write_pos = mca_pc_write_pos; bus->f.mca_read_pos = mca_pc_read_pos; bus->f.mca_transform_irq = mca_dummy_transform_irq; bus->f.mca_transform_ioport = mca_dummy_transform_ioport; bus->f.mca_transform_memory = mca_dummy_transform_memory; /* get the motherboard device */ mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); if (unlikely(!mca_dev)) goto out_nomem; /* * We do not expect many MCA interrupts during initialization, * but let us be safe: */ spin_lock_irq(&mca_lock); /* Make sure adapter setup is off */ outb_p(0, MCA_ADAPTER_SETUP_REG); /* Read motherboard POS registers */ mca_dev->pos_register = 0x7f; outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); mca_dev->name[0] = 0; mca_read_and_store_pos(mca_dev->pos); mca_configure_adapter_status(mca_dev); /* fake POS and slot for a motherboard */ mca_dev->pos_id = MCA_MOTHERBOARD_POS; mca_dev->slot = MCA_MOTHERBOARD; mca_register_device(MCA_PRIMARY_BUS, mca_dev); mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if (unlikely(!mca_dev)) goto out_unlock_nomem; /* Put motherboard into video setup mode, read integrated video * POS registers, and turn motherboard setup off. */ mca_dev->pos_register = 0xdf; outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); mca_dev->name[0] = 0; mca_read_and_store_pos(mca_dev->pos); mca_configure_adapter_status(mca_dev); /* fake POS and slot for the integrated video */ mca_dev->pos_id = MCA_INTEGVIDEO_POS; mca_dev->slot = MCA_INTEGVIDEO; mca_register_device(MCA_PRIMARY_BUS, mca_dev); /* * 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. */ for (i = 0; (which_scsi = mca_builtin_scsi_ports[i]) != 0; i++) { outb_p(which_scsi, MCA_MOTHERBOARD_SETUP_REG); if (mca_read_and_store_pos(pos)) break; } if (which_scsi) { /* found a scsi card */ mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if (unlikely(!mca_dev)) goto out_unlock_nomem; for (j = 0; j < 8; j++) mca_dev->pos[j] = pos[j]; mca_configure_adapter_status(mca_dev); /* fake POS and slot for integrated SCSI controller */ mca_dev->pos_id = MCA_INTEGSCSI_POS; mca_dev->slot = MCA_INTEGSCSI; mca_dev->pos_register = which_scsi; mca_register_device(MCA_PRIMARY_BUS, mca_dev); } /* 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); if (!mca_read_and_store_pos(pos)) continue; mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if (unlikely(!mca_dev)) goto out_unlock_nomem; for (j = 0; j < 8; j++) mca_dev->pos[j] = pos[j]; mca_dev->driver_loaded = 0; mca_dev->slot = i; mca_dev->pos_register = 0; mca_configure_adapter_status(mca_dev); mca_register_device(MCA_PRIMARY_BUS, mca_dev); } outb_p(0, MCA_ADAPTER_SETUP_REG); /* Enable interrupts and return memory start */ spin_unlock_irq(&mca_lock); for (i = 0; i < MCA_STANDARD_RESOURCES; i++) request_resource(&ioport_resource, mca_standard_resources + i); mca_do_proc_init(); return 0; out_unlock_nomem: spin_unlock_irq(&mca_lock); out_nomem: printk(KERN_EMERG "Failed memory allocation in MCA setup!\n"); return -ENOMEM; }
static int __init mca_init(void) { unsigned int i, j; struct mca_device *mca_dev; unsigned char pos[8]; short mca_builtin_scsi_ports[] = {0xf7, 0xfd, 0x00}; struct mca_bus *bus; if (mca_system_init()) { printk(KERN_ERR "MCA bus system initialisation failed\n"); return -ENODEV; } if (!MCA_bus) return -ENODEV; printk(KERN_INFO "Micro Channel bus detected.\n"); bus = mca_attach_bus(MCA_PRIMARY_BUS); if (!bus) goto out_nomem; bus->default_dma_mask = 0xffffffffLL; bus->f.mca_write_pos = mca_pc_write_pos; bus->f.mca_read_pos = mca_pc_read_pos; bus->f.mca_transform_irq = mca_dummy_transform_irq; bus->f.mca_transform_ioport = mca_dummy_transform_ioport; bus->f.mca_transform_memory = mca_dummy_transform_memory; mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); if (unlikely(!mca_dev)) goto out_nomem; spin_lock_irq(&mca_lock); outb_p(0, MCA_ADAPTER_SETUP_REG); mca_dev->pos_register = 0x7f; outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); mca_dev->name[0] = 0; mca_read_and_store_pos(mca_dev->pos); mca_configure_adapter_status(mca_dev); mca_dev->pos_id = MCA_MOTHERBOARD_POS; mca_dev->slot = MCA_MOTHERBOARD; mca_register_device(MCA_PRIMARY_BUS, mca_dev); mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if (unlikely(!mca_dev)) goto out_unlock_nomem; mca_dev->pos_register = 0xdf; outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); mca_dev->name[0] = 0; mca_read_and_store_pos(mca_dev->pos); mca_configure_adapter_status(mca_dev); mca_dev->pos_id = MCA_INTEGVIDEO_POS; mca_dev->slot = MCA_INTEGVIDEO; mca_register_device(MCA_PRIMARY_BUS, mca_dev); for (i = 0; (which_scsi = mca_builtin_scsi_ports[i]) != 0; i++) { outb_p(which_scsi, MCA_MOTHERBOARD_SETUP_REG); if (mca_read_and_store_pos(pos)) break; } if (which_scsi) { mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if (unlikely(!mca_dev)) goto out_unlock_nomem; for (j = 0; j < 8; j++) mca_dev->pos[j] = pos[j]; mca_configure_adapter_status(mca_dev); mca_dev->pos_id = MCA_INTEGSCSI_POS; mca_dev->slot = MCA_INTEGSCSI; mca_dev->pos_register = which_scsi; mca_register_device(MCA_PRIMARY_BUS, mca_dev); } outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); for (i = 0; i < MCA_MAX_SLOT_NR; i++) { outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG); if (!mca_read_and_store_pos(pos)) continue; mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if (unlikely(!mca_dev)) goto out_unlock_nomem; for (j = 0; j < 8; j++) mca_dev->pos[j] = pos[j]; mca_dev->driver_loaded = 0; mca_dev->slot = i; mca_dev->pos_register = 0; mca_configure_adapter_status(mca_dev); mca_register_device(MCA_PRIMARY_BUS, mca_dev); } outb_p(0, MCA_ADAPTER_SETUP_REG); spin_unlock_irq(&mca_lock); for (i = 0; i < MCA_STANDARD_RESOURCES; i++) request_resource(&ioport_resource, mca_standard_resources + i); mca_do_proc_init(); return 0; out_unlock_nomem: spin_unlock_irq(&mca_lock); out_nomem: printk(KERN_EMERG "Failed memory allocation in MCA setup!\n"); return -ENOMEM; }