コード例 #1
0
static void getaddrs(struct mca_device *mdev, int *base, int *memlen,
		     int *iobase, int *irq, ibmlana_medium *medium)
{
	u_char pos0, pos1;

	pos0 = mca_device_read_stored_pos(mdev, 2);
	pos1 = mca_device_read_stored_pos(mdev, 3);

	*base = 0xc0000 + ((pos1 & 0xf0) << 9);
	*memlen = (pos1 & 0x01) ? 0x8000 : 0x4000;
	*iobase = (pos0 & 0xe0) << 7;
	switch (pos0 & 0x06) {
	case 0:
		*irq = 5;
		break;
	case 2:
		*irq = 15;
		break;
	case 4:
		*irq = 10;
		break;
	case 6:
		*irq = 11;
		break;
	}
	*medium = (pos0 & 0x18) >> 3;
}
コード例 #2
0
ファイル: mca-legacy.c プロジェクト: 274914765/C
/**
 *    mca_read_stored_pos - read POS register from boot data
 *    @slot: slot number to read from
 *    @reg:  register to read from
 *
 *    Fetch a POS value that was stored at boot time by the kernel
 *    when it scanned the MCA space. The register value is returned.
 *    Missing or invalid registers report 0.
 */
unsigned char mca_read_stored_pos(int slot, int reg)
{
    struct mca_device *mca_dev = mca_find_device_by_slot(slot);

    if(!mca_dev)
        return 0;

    return mca_device_read_stored_pos(mca_dev, reg);
}
コード例 #3
0
ファイル: sim710.c プロジェクト: rrowicki/Chrono_Kernel-1
static __init int
sim710_mca_probe(struct device *dev)
{
	struct mca_device *mca_dev = to_mca_device(dev);
	int slot = mca_dev->slot;
	int pos[3];
	unsigned int base;
	int irq_vector;
	short id = sim710_mca_id_table[mca_dev->index];
	static int io_004f_by_pos[] = MCA_004F_IO_PORTS;
	static int irq_004f_by_pos[] = MCA_004F_IRQS;
	static int io_01bb_by_pos[] = MCA_01BB_IO_PORTS;
	static int irq_01bb_by_pos[] = MCA_01BB_IRQS;
	char *name;
	int clock;

	pos[0] = mca_device_read_stored_pos(mca_dev, 2);
	pos[1] = mca_device_read_stored_pos(mca_dev, 3);
	pos[2] = mca_device_read_stored_pos(mca_dev, 4);

	/*
	 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
	 *
	 *    000000  <disabled>   001010  0x2800
	 *    000001  <invalid>    001011  0x2C00
	 *    000010  0x0800       001100  0x3000
	 *    000011  0x0C00       001101  0x3400
	 *    000100  0x1000       001110  0x3800
	 *    000101  0x1400       001111  0x3C00
	 *    000110  0x1800       010000  0x4000
	 *    000111  0x1C00       010001  0x4400
	 *    001000  0x2000       010010  0x4800
	 *    001001  0x2400       010011  0x4C00
	 *                         010100  0x5000
	 *
	 * 00F4 port base by bits 3,2,1 in pos[0]
	 *
	 *    000  <disabled>      001    0x200
	 *    010  0x300           011    0x400
	 *    100  0x500           101    0x600
	 *
	 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
	 *
	 *    00   3               10   11
	 *    01   5               11   14
	 *
	 * 00F4 IRQ specified by bits 6,5,4 in pos[0]
	 *
	 *    100   5              101    9
	 *    110   14
	 */

	if (id == 0x01bb || id == 0x01ba) {
		base = io_01bb_by_pos[(pos[2] & 0xFC) >> 2];
		irq_vector =
			irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];

		clock = 50;
		if (id == 0x01bb)
			name = "NCR 3360/3430 SCSI SubSystem";
		else
			name = "NCR Dual SIOP SCSI Host Adapter Board";
	} else if ( id == 0x004f ) {
コード例 #4
0
int __init ultramca_probe(struct device *gen_dev)
{
	unsigned short ioaddr;
	struct net_device *dev;
	unsigned char reg4, num_pages;
	struct mca_device *mca_dev = to_mca_device(gen_dev);
	char slot = mca_dev->slot;
	unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff;
	int i, rc;
	int adapter = mca_dev->index;
	int tbase = 0;
	int tirq = 0;
	int base_addr = ultra_io[ultra_found];
	int irq = ultra_irq[ultra_found];

	if (base_addr || irq) {
		printk(KERN_INFO "Probing for SMC MCA adapter");
		if (base_addr) {
			printk(KERN_INFO " at I/O address 0x%04x%c",
			       base_addr, irq ? ' ' : '\n');
		}
		if (irq) {
			printk(KERN_INFO "using irq %d\n", irq);
		}
	}

	tirq = 0;
	tbase = 0;

	/* If we're trying to match a specificied irq or io address,
	 * we'll reject the adapter found unless it's the one we're
	 * looking for */

	pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */
	pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */
	pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */
	pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */

	/* Test the following conditions:
	 * - If an irq parameter is supplied, compare it
	 *   with the irq of the adapter we found
	 * - If a base_addr paramater is given, compare it
	 *   with the base_addr of the adapter we found
	 * - Check that the irq and the base_addr of the
	 *   adapter we found is not already in use by
	 *   this driver
	 */

	switch (mca_dev->index) {
	case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
	case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
	case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
	case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
		{
			tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr;
			tirq  = irq_table[(pos5 & 0xc) >> 2].new_irq;
			break;
		}
	case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
	case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
	case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
	case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
		{
			tbase = ((pos2 & 0x0fe) * 0x10);
			tirq  = irq_table[(pos5 & 3)].old_irq;
			break;
		}
	}
	
	if(!tirq || !tbase 
	   || (irq && irq != tirq) 
	   || (base_addr && tbase != base_addr))
		/* FIXME: we're trying to force the ordering of the
		 * devices here, there should be a way of getting this
		 * to happen */
		return -ENXIO;

        /* Adapter found. */
	dev  = alloc_ei_netdev();
	if(!dev)
		return -ENODEV;

	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, gen_dev);
	mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]);
	mca_device_set_claim(mca_dev, 1);

	printk(KERN_INFO "smc_mca: %s found in slot %d\n",
		       smc_mca_adapter_names[adapter], slot + 1);

	ultra_found++;

	dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase);
	dev->irq       = mca_device_transform_irq(mca_dev, tirq);
	dev->mem_start = 0;
	num_pages      = 40;

	switch (adapter) {	/* card-# in const array above [hs] */
		case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
		case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
		{
			for (i = 0; i < 16; i++) { /* taking 16 counts
						    * up to 15 [hs] */
				if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) {
					dev->mem_start = (unsigned long)
					  mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start);
					num_pages = mem_table[i].num_pages;
				}
			}
			break;
		}
		case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
		case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
		case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
		case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
		{
			dev->mem_start = (unsigned long)
			  mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000));
			num_pages = 0x40;
			break;
		}
		case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
		case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
		{
			/* courtesy of [email protected], pos3 indicates
			 * the index of the 0x2000 step.
			 * beware different number of pages [hs]
			 */
			dev->mem_start = (unsigned long) 
			  mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf))));
			num_pages = 0x20 + (2 * (pos3 & 0x10));
			break;
		}
	}

	/* sanity check, shouldn't happen */
	if (dev->mem_start == 0) {
		rc = -ENODEV;
		goto err_unclaim;
	}

	if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) {
		rc = -ENODEV;
		goto err_unclaim;
	}

	reg4 = inb(ioaddr + 4) & 0x7f;
	outb(reg4, ioaddr + 4);

	printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x,", slot + 1, ioaddr);

	for (i = 0; i < 6; i++)
		printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));

	/* Switch from the station address to the alternate register set
	 * and read the useful registers there.
	 */

	outb(0x80 | reg4, ioaddr + 4);

	/* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot.
	 */

	outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);

	/* Switch back to the station address register set so that
	 * the MS-DOS driver can find the card after a warm boot.
	 */

	outb(reg4, ioaddr + 4);

	gen_dev->driver_data = dev;

	/* The 8390 isn't at the base address, so fake the offset
	 */

	dev->base_addr = ioaddr + ULTRA_NIC_OFFSET;

	ei_status.name = "SMC Ultra MCA";
	ei_status.word16 = 1;
	ei_status.tx_start_page = START_PG;
	ei_status.rx_start_page = START_PG + TX_PAGES;
	ei_status.stop_page = num_pages;

	ei_status.rmem_start = dev->mem_start + TX_PAGES * 256;
	dev->mem_end = ei_status.rmem_end =
	dev->mem_start + (ei_status.stop_page - START_PG) * 256;

	printk(", IRQ %d memory %#lx-%#lx.\n",
	dev->irq, dev->mem_start, dev->mem_end - 1);

	ei_status.reset_8390 = &ultramca_reset_8390;
	ei_status.block_input = &ultramca_block_input;
	ei_status.block_output = &ultramca_block_output;
	ei_status.get_8390_hdr = &ultramca_get_8390_hdr;

	ei_status.priv = slot;

	dev->open = &ultramca_open;
	dev->stop = &ultramca_close_card;
#ifdef CONFIG_NET_POLL_CONTROLLER
	dev->poll_controller = ei_poll;
#endif

	NS8390_init(dev, 0);

	rc = register_netdev(dev);
	if (rc)
		goto err_release_region;

	return 0;

err_release_region:
	release_region(ioaddr, ULTRA_IO_EXTENT);
err_unclaim:
	mca_device_set_claim(mca_dev, 0);
	free_netdev(dev);
	return rc;
}