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; }