Esempio n. 1
0
void
adv_intr(void *arg)
{
	struct	  adv_softc *adv;
	u_int16_t chipstat;
	u_int16_t saved_ram_addr;
	u_int8_t  ctrl_reg;
	u_int8_t  saved_ctrl_reg;
	u_int8_t  host_flag;

	adv = (struct adv_softc *)arg;

	chipstat = ADV_INW(adv, ADV_CHIP_STATUS);

	/* Is it for us? */
	if ((chipstat & (ADV_CSW_INT_PENDING|ADV_CSW_SCSI_RESET_LATCH)) == 0)
		return;

	ctrl_reg = ADV_INB(adv, ADV_CHIP_CTRL);
	saved_ctrl_reg = ctrl_reg & (~(ADV_CC_SCSI_RESET | ADV_CC_CHIP_RESET |
				       ADV_CC_SINGLE_STEP | ADV_CC_DIAG |
				       ADV_CC_TEST));

	if ((chipstat & (ADV_CSW_SCSI_RESET_LATCH|ADV_CSW_SCSI_RESET_ACTIVE))) {
		printf("Detected Bus Reset\n");
		adv_reset_bus(adv, /*initiate_reset*/FALSE);
		return;
	}

	if ((chipstat & ADV_CSW_INT_PENDING) != 0) {
		
		saved_ram_addr = ADV_INW(adv, ADV_LRAM_ADDR);
		host_flag = adv_read_lram_8(adv, ADVV_HOST_FLAG_B);
		adv_write_lram_8(adv, ADVV_HOST_FLAG_B,
				 host_flag | ADV_HOST_FLAG_IN_ISR);

		adv_ack_interrupt(adv);
		
		if ((chipstat & ADV_CSW_HALTED) != 0
		 && (ctrl_reg & ADV_CC_SINGLE_STEP) != 0) {
			adv_isr_chip_halted(adv);
			saved_ctrl_reg &= ~ADV_CC_HALT;
		} else {
			adv_run_doneq(adv);
		}
		ADV_OUTW(adv, ADV_LRAM_ADDR, saved_ram_addr);
#ifdef DIAGNOSTIC	
		if (ADV_INW(adv, ADV_LRAM_ADDR) != saved_ram_addr)
			panic("adv_intr: Unable to set LRAM addr");
#endif	
		adv_write_lram_8(adv, ADVV_HOST_FLAG_B, host_flag);
	}
	
	ADV_OUTB(adv, ADV_CHIP_CTRL, saved_ctrl_reg);
}
Esempio n. 2
0
static int
adv_set_isa_dma_settings(struct adv_softc *adv)
{
	u_int16_t cfg_lsw;
	u_int8_t  value;

	if ((adv->isa_dma_channel >= 5) && (adv->isa_dma_channel <= 7)) { 
	        if (adv->isa_dma_channel == 7)
			value = 0x00;
		else     
			value = adv->isa_dma_channel - 4;
		cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW)
			& ~ADV_CFG_LSW_ISA_DMA_CHANNEL;  
		cfg_lsw |= value;
		ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);

		adv->isa_dma_speed &= 0x07;
		adv_set_bank(adv, 1);
		ADV_OUTB(adv, ADV_DMA_SPEED, adv->isa_dma_speed);
		adv_set_bank(adv, 0);
		isa_dmacascade(adv->isa_dma_channel);
	}
	return (0);
}
Esempio n. 3
0
static int
adv_pci_attach(device_t dev)
{
	struct		adv_softc *adv;
	u_int32_t	id;
	u_int32_t	command;
	int		error, rid, irqrid;
	void		*ih;
	struct resource	*iores, *irqres;

	/*
	 * Determine the chip version.
	 */
	id = pci_read_config(dev, PCIR_DEVVENDOR, /*bytes*/4);
	command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);

	/*
	 * These cards do not allow memory mapped accesses, so we must
	 * ensure that I/O accesses are available or we won't be able
	 * to talk to them.
	 */
	if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
	 != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
		command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
		pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
	}

	/*
	 * Early chips can't handle non-zero latency timer settings.
	 */
	if (id == PCI_DEVICE_ID_ADVANSYS_1200A
	 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
		pci_write_config(dev, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
	}

	rid = PCI_BASEADR0;
	iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
				   RF_ACTIVE);
	if (iores == NULL)
		return ENXIO;

	if (adv_find_signature(rman_get_bustag(iores),
			       rman_get_bushandle(iores)) == 0) {
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv = adv_alloc(dev, rman_get_bustag(iores), rman_get_bushandle(iores));
	if (adv == NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	/* Allocate a dmatag for our transfer DMA maps */
	/* XXX Should be a child of the PCI bus dma tag */
	error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
				   /*boundary*/0,
				   /*lowaddr*/ADV_PCI_MAX_DMA_ADDR,
				   /*highaddr*/BUS_SPACE_MAXADDR,
				   /*filter*/NULL, /*filterarg*/NULL,
				   /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
				   /*nsegments*/BUS_SPACE_UNRESTRICTED,
				   /*maxsegsz*/ADV_PCI_MAX_DMA_COUNT,
				   /*flags*/0,
				   &adv->parent_dmat);
 
	if (error != 0) {
		kprintf("%s: Could not allocate DMA tag - error %d\n",
		       adv_name(adv), error);
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv->init_level++;

	if (overrun_buf == NULL) {
		/* Need to allocate our overrun buffer */
		if (bus_dma_tag_create(adv->parent_dmat,
				       /*alignment*/8, /*boundary*/0,
				       ADV_PCI_MAX_DMA_ADDR, BUS_SPACE_MAXADDR,
				       /*filter*/NULL, /*filterarg*/NULL,
				       ADV_OVERRUN_BSIZE, /*nsegments*/1,
				       BUS_SPACE_MAXSIZE_32BIT, /*flags*/0,
				       &overrun_dmat) != 0) {
			bus_dma_tag_destroy(adv->parent_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
			return ENXIO;
       		}
		if (bus_dmamem_alloc(overrun_dmat,
				     (void *)&overrun_buf,
				     BUS_DMA_NOWAIT,
				     &overrun_dmamap) != 0) {
			bus_dma_tag_destroy(overrun_dmat);
			bus_dma_tag_destroy(adv->parent_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
			return ENXIO;
		}
		/* And permanently map it in */  
		bus_dmamap_load(overrun_dmat, overrun_dmamap,
				overrun_buf, ADV_OVERRUN_BSIZE,
				adv_map, &overrun_physbase,
				/*flags*/0);
	}

	adv->overrun_physbase = overrun_physbase;
			
	/*
	 * Stop the chip.
	 */
	ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
	ADV_OUTW(adv, ADV_CHIP_STATUS, 0);

	adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
	adv->type = ADV_PCI;
	
	/*
	 * Setup active negation and signal filtering.
	 */
	{
		u_int8_t extra_cfg;

		if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150)
			adv->type |= ADV_ULTRA;
		if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
			extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
		else
			extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
		ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
	}

	if (adv_init(adv) != 0) {
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
	adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;

#if CC_DISABLE_PCI_PARITY_INT
	{
		u_int16_t config_msw;

		config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
		config_msw &= 0xFFC0;
		ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw); 
	}
#endif
 
	if (id == PCI_DEVICE_ID_ADVANSYS_1200A
	 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
		adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
		adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
		adv->fix_asyn_xfer = ~0;
	}

	irqrid = 0;
	irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &irqrid, 0, ~0, 1,
				    RF_SHAREABLE | RF_ACTIVE);
	if (irqres == NULL ||
	    bus_setup_intr(dev, irqres, 0, adv_intr, adv, &ih, NULL)) {
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv_attach(adv);
	return 0;
}
Esempio n. 4
0
static int
adv_isa_probe(device_t dev)
{
	int	port_index;
	int	max_port_index;
	u_long	iobase, iocount, irq;
	int	user_iobase = 0;
	int	rid = 0;
	void	*ih;
	struct resource	*iores, *irqres;

	/*
	 * We don't know of any PnP ID's for these cards.
	 */
	if (isa_get_logicalid(dev) != 0)
		return (ENXIO);

	/*
	 * Default to scanning all possible device locations.
	 */
	port_index = 0;
	max_port_index = MAX_ISA_IOPORT_INDEX;

	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, &iocount) == 0) {
		user_iobase = 1;
		for (;port_index <= max_port_index; port_index++)
			if (iobase <= adv_isa_ioports[port_index])
				break;
		if ((port_index > max_port_index)
		 || (iobase != adv_isa_ioports[port_index])) {
			if (bootverbose)
			    printf("adv%d: Invalid baseport of 0x%lx specified. "
				"Nearest valid baseport is 0x%x.  Failing "
				"probe.\n", device_get_unit(dev), iobase,
				(port_index <= max_port_index) ?
					adv_isa_ioports[port_index] :
					adv_isa_ioports[max_port_index]);
			return ENXIO;
		}
		max_port_index = port_index;
	}

	/* Perform the actual probing */
	adv_set_isapnp_wait_for_key();
	for (;port_index <= max_port_index; port_index++) {
		u_int16_t port_addr = adv_isa_ioports[port_index];
		bus_size_t maxsegsz;
		bus_size_t maxsize;
		bus_addr_t lowaddr;
		int error;
		struct adv_softc *adv;

		if (port_addr == 0)
			/* Already been attached */
			continue;
		
		if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port_addr, 1))
			continue;

		/* XXX what is the real portsize? */
		iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
					       RF_ACTIVE);
		if (iores == NULL)
			continue;

		if (adv_find_signature(rman_get_bustag(iores),
				       rman_get_bushandle(iores)) == 0) {
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			continue;
		}

		/*
		 * Got one.  Now allocate our softc
		 * and see if we can initialize the card.
		 */
		adv = adv_alloc(dev, rman_get_bustag(iores),
				rman_get_bushandle(iores));
		if (adv == NULL) {
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		/*
		 * Stop the chip.
		 */
		ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
		ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
		/*
		 * Determine the chip version.
		 */
		adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
		if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL)
		    && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) {
			adv->type = ADV_VL;
			maxsegsz = ADV_VL_MAX_DMA_COUNT;
			maxsize = BUS_SPACE_MAXSIZE_32BIT;
			lowaddr = ADV_VL_MAX_DMA_ADDR;
			bus_delete_resource(dev, SYS_RES_DRQ, 0);
		} else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA)
			   && (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) {
			if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) {
				adv->type = ADV_ISAPNP;
				ADV_OUTB(adv, ADV_REG_IFC,
					 ADV_IFC_INIT_DEFAULT);
			} else {
				adv->type = ADV_ISA;
			}
			maxsegsz = ADV_ISA_MAX_DMA_COUNT;
			maxsize = BUS_SPACE_MAXSIZE_24BIT;
			lowaddr = ADV_ISA_MAX_DMA_ADDR;
			adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED;
			adv->isa_dma_channel = adv_get_isa_dma_channel(adv);
			bus_set_resource(dev, SYS_RES_DRQ, 0,
					 adv->isa_dma_channel, 1);
		} else {
			panic("advisaprobe: Unknown card revision\n");
		}

		/*
		 * Allocate a parent dmatag for all tags created
		 * by the MI portions of the advansys driver
		 */
		error = bus_dma_tag_create(
				/* parent	*/ bus_get_dma_tag(dev),
				/* alignemnt	*/ 1,
				/* boundary	*/ 0,
				/* lowaddr	*/ lowaddr,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ NULL,
				/* filterarg	*/ NULL,
				/* maxsize	*/ maxsize,
				/* nsegments	*/ ~0,
				/* maxsegsz	*/ maxsegsz,
				/* flags	*/ 0,
				/* lockfunc	*/ busdma_lock_mutex,
				/* lockarg	*/ &Giant,
				&adv->parent_dmat); 

		if (error != 0) {
			printf("%s: Could not allocate DMA tag - error %d\n",
			       adv_name(adv), error); 
			adv_free(adv); 
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		adv->init_level += 2;

		if (overrun_buf == NULL) {
			/* Need to allocate our overrun buffer */
			if (bus_dma_tag_create(
				/* parent	*/ adv->parent_dmat,
				/* alignment	*/ 8,
				/* boundary	*/ 0,
				/* lowaddr	*/ ADV_ISA_MAX_DMA_ADDR,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ NULL,
				/* filterarg	*/ NULL,
				/* maxsize	*/ ADV_OVERRUN_BSIZE,
				/* nsegments	*/ 1,
				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
				/* flags	*/ 0,
				/* lockfunc	*/ NULL,
				/* lockarg	*/ NULL,
				&overrun_dmat) != 0) {
				adv_free(adv);
				bus_release_resource(dev, SYS_RES_IOPORT, 0,
						     iores);
				break;
			}
			if (bus_dmamem_alloc(overrun_dmat,
					     (void **)&overrun_buf,
					     BUS_DMA_NOWAIT,
					     &overrun_dmamap) != 0) {
				bus_dma_tag_destroy(overrun_dmat);
				adv_free(adv);
				bus_release_resource(dev, SYS_RES_IOPORT, 0,
						     iores);
				break;
			}
			/* And permanently map it in */  
			bus_dmamap_load(overrun_dmat, overrun_dmamap,
					overrun_buf, ADV_OVERRUN_BSIZE,
					adv_map, &overrun_physbase,
					/*flags*/0);
		}

		adv->overrun_physbase = overrun_physbase;

		if (adv_init(adv) != 0) {
			bus_dmamap_unload(overrun_dmat, overrun_dmamap);
			bus_dmamem_free(overrun_dmat, overrun_buf,
			    overrun_dmamap);
			bus_dma_tag_destroy(overrun_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		switch (adv->type) {
		case ADV_ISAPNP:
			if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG) {
				adv->bug_fix_control
				    |= ADV_BUG_FIX_ASYN_USE_SYN;
				adv->fix_asyn_xfer = ~0;
			}
			/* Fall Through */
		case ADV_ISA:
			adv->max_dma_count = ADV_ISA_MAX_DMA_COUNT;
			adv->max_dma_addr = ADV_ISA_MAX_DMA_ADDR;
			adv_set_isa_dma_settings(adv);
			break;

		case ADV_VL:
			adv->max_dma_count = ADV_VL_MAX_DMA_COUNT;
			adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR;
			break;
		default:
			panic("advisaprobe: Invalid card type\n");
		}
			
		/* Determine our IRQ */
		if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL))
			bus_set_resource(dev, SYS_RES_IRQ, 0,
					 adv_get_chip_irq(adv), 1);
		else
			adv_set_chip_irq(adv, irq);

		irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
						RF_ACTIVE);
		if (irqres == NULL ||
		    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY,
		        NULL, adv_intr, adv, &ih)) {
			bus_dmamap_unload(overrun_dmat, overrun_dmamap);
			bus_dmamem_free(overrun_dmat, overrun_buf,
			    overrun_dmamap);
			bus_dma_tag_destroy(overrun_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		/* Mark as probed */
		adv_isa_ioports[port_index] = 0;
		return 0;
	}

	if (user_iobase)
		bus_set_resource(dev, SYS_RES_IOPORT, 0, iobase, iocount);
	else
		bus_delete_resource(dev, SYS_RES_IOPORT, 0);

	return ENXIO;
}
Esempio n. 5
0
int
adv_init(struct adv_softc *adv)
{
	struct	  adv_eeprom_config eeprom_config;
	int	  checksum, i;
	int	  max_sync;
	u_int16_t config_lsw;
	u_int16_t config_msw;

	adv_lib_init(adv);

  	/*
	 * Stop script execution.
	 */  
	adv_write_lram_16(adv, ADV_HALTCODE_W, 0x00FE);
	adv_stop_execution(adv);
	if (adv_stop_chip(adv) == 0 || adv_is_chip_halted(adv) == 0) {
		printf("adv%d: Unable to halt adapter. Initialization"
		       "failed\n", adv->unit);
		return (1);
	}
	ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
	if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
		printf("adv%d: Unable to set program counter. Initialization"
		       "failed\n", adv->unit);
		return (1);
	}

	config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
	config_lsw = ADV_INW(adv, ADV_CONFIG_LSW);

	if ((config_msw & ADV_CFG_MSW_CLR_MASK) != 0) {
		config_msw &= ~ADV_CFG_MSW_CLR_MASK;
		/*
		 * XXX The Linux code flags this as an error,
		 * but what should we report to the user???
		 * It seems that clearing the config register
		 * makes this error recoverable.
		 */
		ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
	}

	/* Suck in the configuration from the EEProm */
	checksum = adv_get_eeprom_config(adv, &eeprom_config);

	if (ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_AUTO_CONFIG) {
		/*
		 * XXX The Linux code sets a warning level for this
		 * condition, yet nothing of meaning is printed to
		 * the user.  What does this mean???
		 */
		if (adv->chip_version == 3) {
			if (eeprom_config.cfg_lsw != config_lsw)
				eeprom_config.cfg_lsw = config_lsw;
			if (eeprom_config.cfg_msw != config_msw) {
				eeprom_config.cfg_msw = config_msw;
			}
		}
	}
	if (checksum == eeprom_config.chksum) {

		/* Range/Sanity checking */
		if (eeprom_config.max_total_qng < ADV_MIN_TOTAL_QNG) {
			eeprom_config.max_total_qng = ADV_MIN_TOTAL_QNG;
		}
		if (eeprom_config.max_total_qng > ADV_MAX_TOTAL_QNG) {
			eeprom_config.max_total_qng = ADV_MAX_TOTAL_QNG;
		}
		if (eeprom_config.max_tag_qng > eeprom_config.max_total_qng) {
			eeprom_config.max_tag_qng = eeprom_config.max_total_qng;
		}
		if (eeprom_config.max_tag_qng < ADV_MIN_TAG_Q_PER_DVC) {
			eeprom_config.max_tag_qng = ADV_MIN_TAG_Q_PER_DVC;
		}
		adv->max_openings = eeprom_config.max_total_qng;
		adv->user_disc_enable = eeprom_config.disc_enable;
		adv->user_cmd_qng_enabled = eeprom_config.use_cmd_qng;
		adv->isa_dma_speed = EEPROM_DMA_SPEED(eeprom_config);
		adv->scsi_id = EEPROM_SCSIID(eeprom_config) & ADV_MAX_TID;
		EEPROM_SET_SCSIID(eeprom_config, adv->scsi_id);
		adv->control = eeprom_config.cntl;
		for (i = 0; i <= ADV_MAX_TID; i++) {
			u_int8_t sync_data;

			if ((eeprom_config.init_sdtr & (0x1 << i)) == 0)
				sync_data = 0;
			else
				sync_data = eeprom_config.sdtr_data[i];
			adv_sdtr_to_period_offset(adv,
						  sync_data,
						  &adv->tinfo[i].user.period,
						  &adv->tinfo[i].user.offset,
						  i);
		}
		config_lsw = eeprom_config.cfg_lsw;
		eeprom_config.cfg_msw = config_msw;
	} else {
		u_int8_t sync_data;

		printf("adv%d: Warning EEPROM Checksum mismatch. "
		       "Using default device parameters\n", adv->unit);

		/* Set reasonable defaults since we can't read the EEPROM */
		adv->isa_dma_speed = /*ADV_DEF_ISA_DMA_SPEED*/1;
		adv->max_openings = ADV_DEF_MAX_TOTAL_QNG;
		adv->disc_enable = TARGET_BIT_VECTOR_SET;
		adv->user_disc_enable = TARGET_BIT_VECTOR_SET;
		adv->cmd_qng_enabled = TARGET_BIT_VECTOR_SET;
		adv->user_cmd_qng_enabled = TARGET_BIT_VECTOR_SET;
		adv->scsi_id = 7;
		adv->control = 0xFFFF;

		if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
			/* Default to no Ultra to support the 3030 */
			adv->control &= ~ADV_CNTL_SDTR_ENABLE_ULTRA;
		sync_data = ADV_DEF_SDTR_OFFSET | (ADV_DEF_SDTR_INDEX << 4);
		for (i = 0; i <= ADV_MAX_TID; i++) {
			adv_sdtr_to_period_offset(adv, sync_data,
						  &adv->tinfo[i].user.period,
						  &adv->tinfo[i].user.offset,
						  i);
		}
		config_lsw |= ADV_CFG_LSW_SCSI_PARITY_ON;
	}
	config_msw &= ~ADV_CFG_MSW_CLR_MASK;
	config_lsw |= ADV_CFG_LSW_HOST_INT_ON;
	if ((adv->type & (ADV_PCI|ADV_ULTRA)) == (ADV_PCI|ADV_ULTRA)
	 && (adv->control & ADV_CNTL_SDTR_ENABLE_ULTRA) == 0)
		/* 25ns or 10MHz */
		max_sync = 25;
	else
		/* Unlimited */
		max_sync = 0;
	for (i = 0; i <= ADV_MAX_TID; i++) {
		if (adv->tinfo[i].user.period < max_sync)
			adv->tinfo[i].user.period = max_sync;
	}

	if (adv_test_external_lram(adv) == 0) {
		if ((adv->type & (ADV_PCI|ADV_ULTRA)) == (ADV_PCI|ADV_ULTRA)) {
			eeprom_config.max_total_qng =
			    ADV_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
			eeprom_config.max_tag_qng =
			    ADV_MAX_PCI_ULTRA_INRAM_TAG_QNG;
		} else {
			eeprom_config.cfg_msw |= 0x0800;
			config_msw |= 0x0800;
			eeprom_config.max_total_qng =
			     ADV_MAX_PCI_INRAM_TOTAL_QNG;
			eeprom_config.max_tag_qng = ADV_MAX_INRAM_TAG_QNG;
		}
		adv->max_openings = eeprom_config.max_total_qng;
	}
	ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
	ADV_OUTW(adv, ADV_CONFIG_LSW, config_lsw);
#if 0
	/*
	 * Don't write the eeprom data back for now.
	 * I'd rather not mess up the user's card.  We also don't
	 * fully sanitize the eeprom settings above for the write-back
	 * to be 100% correct.
	 */
	if (adv_set_eeprom_config(adv, &eeprom_config) != 0)
		printf("%s: WARNING! Failure writing to EEPROM.\n",
		       adv_name(adv));
#endif

	adv_set_chip_scsiid(adv, adv->scsi_id);
	if (adv_init_lram_and_mcode(adv))
		return (1);

	adv->disc_enable = adv->user_disc_enable;

	adv_write_lram_8(adv, ADVV_DISC_ENABLE_B, adv->disc_enable); 
	for (i = 0; i <= ADV_MAX_TID; i++) {
		/*
		 * Start off in async mode.
		 */
		adv_set_syncrate(adv, /*struct cam_path */NULL,
				 i, /*period*/0, /*offset*/0,
				 ADV_TRANS_CUR);
		/*
		 * Enable the use of tagged commands on all targets.
		 * This allows the kernel driver to make up it's own mind
		 * as it sees fit to tag queue instead of having the
		 * firmware try and second guess the tag_code settins.
		 */
		adv_write_lram_8(adv, ADVV_MAX_DVC_QNG_BEG + i,
				 adv->max_openings);
	}
	adv_write_lram_8(adv, ADVV_USE_TAGGED_QNG_B, TARGET_BIT_VECTOR_SET);
	adv_write_lram_8(adv, ADVV_CAN_TAGGED_QNG_B, TARGET_BIT_VECTOR_SET);
	printf("adv%d: AdvanSys %s Host Adapter, SCSI ID %d, queue depth %d\n",
	       adv->unit, (adv->type & ADV_ULTRA) && (max_sync == 0)
			  ? "Ultra SCSI" : "SCSI",
	       adv->scsi_id, adv->max_openings);
	return (0);
}
Esempio n. 6
0
static int
adv_pci_attach(device_t dev)
{
	struct		adv_softc *adv;
	u_int32_t	id;
	int		error, rid, irqrid;
	void		*ih;
	struct resource	*iores, *irqres;

	/*
	 * Determine the chip version.
	 */
	id = pci_get_devid(dev);
	pci_enable_busmaster(dev);

	/*
	 * Early chips can't handle non-zero latency timer settings.
	 */
	if (id == PCI_DEVICE_ID_ADVANSYS_1200A
	 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
		pci_write_config(dev, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
	}

	rid = PCI_BASEADR0;
	iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
				       RF_ACTIVE);
	if (iores == NULL)
		return ENXIO;

	if (adv_find_signature(iores) == 0) {
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv = adv_alloc(dev, iores, 0);
	if (adv == NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	/* Allocate a dmatag for our transfer DMA maps */
	error = bus_dma_tag_create(
			/* parent	*/ bus_get_dma_tag(dev),
			/* alignment	*/ 1,
			/* boundary	*/ 0,
			/* lowaddr	*/ ADV_PCI_MAX_DMA_ADDR,
			/* highaddr	*/ BUS_SPACE_MAXADDR,
			/* filter	*/ NULL,
			/* filterarg	*/ NULL,
			/* maxsize	*/ BUS_SPACE_MAXSIZE_32BIT,
			/* nsegments	*/ ~0,
			/* maxsegsz	*/ ADV_PCI_MAX_DMA_COUNT,
			/* flags	*/ 0,
			/* lockfunc	*/ NULL,
			/* lockarg	*/ NULL,
			&adv->parent_dmat);
 
	if (error != 0) {
		device_printf(dev, "Could not allocate DMA tag - error %d\n",
		    error);
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv->init_level++;

	if (overrun_buf == NULL) {
		/* Need to allocate our overrun buffer */
		if (bus_dma_tag_create(
				/* parent	*/ adv->parent_dmat,
				/* alignment	*/ 8,
				/* boundary	*/ 0,
				/* lowaddr	*/ ADV_PCI_MAX_DMA_ADDR,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ NULL,
				/* filterarg	*/ NULL,
				/* maxsize	*/ ADV_OVERRUN_BSIZE,
				/* nsegments	*/ 1,
				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
				/* flags	*/ 0,
				/* lockfunc	*/ NULL,
				/* lockarg	*/ NULL,
				&overrun_dmat) != 0) {
			bus_dma_tag_destroy(adv->parent_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
			return ENXIO;
       		}
		if (bus_dmamem_alloc(overrun_dmat,
				     &overrun_buf,
				     BUS_DMA_NOWAIT,
				     &overrun_dmamap) != 0) {
			bus_dma_tag_destroy(overrun_dmat);
			bus_dma_tag_destroy(adv->parent_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
			return ENXIO;
		}
		/* And permanently map it in */  
		bus_dmamap_load(overrun_dmat, overrun_dmamap,
				overrun_buf, ADV_OVERRUN_BSIZE,
				adv_map, &overrun_physbase,
				/*flags*/0);
	}

	adv->overrun_physbase = overrun_physbase;
			
	/*
	 * Stop the chip.
	 */
	ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
	ADV_OUTW(adv, ADV_CHIP_STATUS, 0);

	adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
	adv->type = ADV_PCI;
	
	/*
	 * Setup active negation and signal filtering.
	 */
	{
		u_int8_t extra_cfg;

		if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150)
			adv->type |= ADV_ULTRA;
		if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
			extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
		else
			extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
		ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
	}

	if (adv_init(adv) != 0) {
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
	adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;

#if defined(CC_DISABLE_PCI_PARITY_INT) && CC_DISABLE_PCI_PARITY_INT
	{
		u_int16_t config_msw;

		config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
		config_msw &= 0xFFC0;
		ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw); 
	}
#endif
 
	if (id == PCI_DEVICE_ID_ADVANSYS_1200A
	 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
		adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
		adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
		adv->fix_asyn_xfer = ~0;
	}

	irqrid = 0;
	irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqrid,
					RF_SHAREABLE | RF_ACTIVE);
	if (irqres == NULL ||
	    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE,
	    NULL, adv_intr, adv, &ih) != 0) {
		if (irqres != NULL)
			bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres);
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}

	if (adv_attach(adv) != 0) {
		bus_teardown_intr(dev, irqres, ih);
		bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres);
		adv_free(adv);
		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
		return ENXIO;
	}
	return 0;
}
Esempio n. 7
0
static int
adv_eisa_attach(device_t dev)
{
	struct adv_softc *adv;
	struct adv_softc *adv_b;
	struct resource *io;
	struct resource *irq;
	int rid, error;
	void *ih;

	adv_b = NULL;

	rid = 0;
	io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
				0, ~0, 1, RF_ACTIVE);
	if (!io) {
		device_printf(dev, "No I/O space?!\n");
		return ENOMEM;
	}

	rid = 0;
	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
				 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
	if (!irq) {
		device_printf(dev, "No irq?!\n");
		bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
		return ENOMEM;

	}

	switch (eisa_get_id(dev) & ~0xF) {
	case EISA_DEVICE_ID_ADVANSYS_750:
		adv_b = adv_alloc(dev, rman_get_bustag(io),
				  rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN2);
		if (adv_b == NULL)
			goto bad;
		
		/*
		 * Allocate a parent dmatag for all tags created
		 * by the MI portions of the advansys driver
		 */
		/* XXX Should be a child of the PCI bus dma tag */
		error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
					   /*boundary*/0,
					   /*lowaddr*/ADV_EISA_MAX_DMA_ADDR,
					   /*highaddr*/BUS_SPACE_MAXADDR,
					   /*filter*/NULL, /*filterarg*/NULL,
					   /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
					   /*nsegments*/~0,
					   /*maxsegsz*/ADV_EISA_MAX_DMA_COUNT,
					   /*flags*/0,
					   &adv_b->parent_dmat);
 
		if (error != 0) {
			printf("%s: Could not allocate DMA tag - error %d\n",
			       adv_name(adv_b), error);
			adv_free(adv_b);
			goto bad;
		}

		adv_b->init_level++;

		/* FALLTHROUGH */
	case EISA_DEVICE_ID_ADVANSYS_740:
		adv = adv_alloc(dev, rman_get_bustag(io),
				rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN1);
		if (adv == NULL) {
			if (adv_b != NULL)
				adv_free(adv_b);
			goto bad;
		}

		/*
		 * Allocate a parent dmatag for all tags created
		 * by the MI portions of the advansys driver
		 */
		/* XXX Should be a child of the PCI bus dma tag */
		error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
					   /*boundary*/0,
					   /*lowaddr*/ADV_EISA_MAX_DMA_ADDR,
					   /*highaddr*/BUS_SPACE_MAXADDR,
					   /*filter*/NULL, /*filterarg*/NULL,
					   /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
					   /*nsegments*/~0,
					   /*maxsegsz*/ADV_EISA_MAX_DMA_COUNT,
					   /*flags*/0,
					   &adv->parent_dmat);
 
		if (error != 0) {
			printf("%s: Could not allocate DMA tag - error %d\n",
			       adv_name(adv), error);
			adv_free(adv);
			goto bad;
		}

		adv->init_level++;
		break;
	default: 
		printf("adveisaattach: Unknown device type!\n");
		goto bad;
		break;
	}

	if (overrun_buf == NULL) {
		/* Need to allocate our overrun buffer */
		if (bus_dma_tag_create(adv->parent_dmat,
				       /*alignment*/8,
				       /*boundary*/0,
				       ADV_EISA_MAX_DMA_ADDR,
				       BUS_SPACE_MAXADDR,
				       /*filter*/NULL,
				       /*filterarg*/NULL,
				       ADV_OVERRUN_BSIZE,
				       /*nsegments*/1,
				       BUS_SPACE_MAXSIZE_32BIT,
				       /*flags*/0,
				       &overrun_dmat) != 0) {
			adv_free(adv);
			goto bad;
       		}
		if (bus_dmamem_alloc(overrun_dmat,
				     (void **)&overrun_buf,
				     BUS_DMA_NOWAIT,
				     &overrun_dmamap) != 0) {
			bus_dma_tag_destroy(overrun_dmat);
			adv_free(adv);
			goto bad;
		}
		/* And permanently map it in */  
		bus_dmamap_load(overrun_dmat, overrun_dmamap,
				overrun_buf, ADV_OVERRUN_BSIZE,
				adv_map, &overrun_physbase,
				/*flags*/0);
	}
	
	/*
	 * Now that we know we own the resources we need, do the 
	 * card initialization.
	 */

	/*
	 * Stop the chip.
	 */
	ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
	ADV_OUTW(adv, ADV_CHIP_STATUS, 0);

	adv->chip_version = EISA_REVISION_ID(eisa_get_id(dev))
			  + ADV_CHIP_MIN_VER_EISA - 1;

	if (adv_init(adv) != 0) {
		adv_free(adv);
		if (adv_b != NULL)
			adv_free(adv_b);
		return(-1);
	}

	adv->max_dma_count = ADV_EISA_MAX_DMA_COUNT;
	adv->max_dma_addr = ADV_EISA_MAX_DMA_ADDR;

	if (adv_b != NULL) {
		/*
		 * Stop the chip.
		 */
		ADV_OUTB(adv_b, ADV_CHIP_CTRL, ADV_CC_HALT);
		ADV_OUTW(adv_b, ADV_CHIP_STATUS, 0);

		adv_b->chip_version = EISA_REVISION_ID(eisa_get_id(dev))
				    + ADV_CHIP_MIN_VER_EISA - 1;

		if (adv_init(adv_b) != 0) {
			adv_free(adv_b);
		} else {
			adv_b->max_dma_count = ADV_EISA_MAX_DMA_COUNT;
			adv_b->max_dma_addr = ADV_EISA_MAX_DMA_ADDR;
		}
	}

	/*
	 * Enable our interrupt handler.
	 */
	bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY, adv_intr, adv, &ih);

	/* Attach sub-devices - always succeeds */
	adv_attach(adv);
	if (adv_b != NULL)
		adv_attach(adv_b);

	return 0;

 bad:
	bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
	bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
	return -1;
}
Esempio n. 8
0
static int
advisaprobe(struct isa_device *id)
{
	int	port_index;
	int	max_port_index;

	/*
	 * Default to scanning all possible device locations.
	 */
	port_index = 0;
	max_port_index = MAX_ISA_IOPORT_INDEX;

	if (id->id_iobase > 0) {
		for (;port_index <= max_port_index; port_index++)
			if (id->id_iobase <= adv_isa_ioports[port_index])
				break;
		if ((port_index > max_port_index)
		 || (id->id_iobase != adv_isa_ioports[port_index])) {
			printf("adv%d: Invalid baseport of 0x%x specified. "
				"Neerest valid baseport is 0x%x.  Failing "
				"probe.\n", id->id_unit, id->id_iobase,
				(port_index <= max_port_index) ?
					adv_isa_ioports[port_index] :
					adv_isa_ioports[max_port_index]);
			return 0;
		}
		max_port_index = port_index;
	}

	/* Perform the actual probing */
	adv_set_isapnp_wait_for_key();
	for (;port_index <= max_port_index; port_index++) {
		u_int16_t port_addr = adv_isa_ioports[port_index];
		bus_size_t maxsegsz;
		bus_size_t maxsize;
		bus_addr_t lowaddr;
		int error;

		if (port_addr == 0)
			/* Already been attached */
			continue;
		id->id_iobase = port_addr;
		if (haveseen_isadev(id, CC_IOADDR | CC_QUIET))
			continue;

		if (adv_find_signature(I386_BUS_SPACE_IO, port_addr)) {
			/*
			 * Got one.  Now allocate our softc
			 * and see if we can initialize the card.
			 */
			struct adv_softc *adv;
			adv = adv_alloc(id->id_unit, I386_BUS_SPACE_IO,
					port_addr);
			if (adv == NULL)
				return (0);

			adv_unit++;

			id->id_iobase = adv->bsh;

			/*
			 * Stop the chip.
			 */
			ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
			ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
			/*
			 * Determine the chip version.
			 */
			adv->chip_version = ADV_INB(adv,
						    ADV_NONEISA_CHIP_REVISION);
			if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL)
			 && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) {
				adv->type = ADV_VL;
				maxsegsz = ADV_VL_MAX_DMA_COUNT;
				maxsize = BUS_SPACE_MAXSIZE_32BIT;
				lowaddr = ADV_VL_MAX_DMA_ADDR;
				id->id_drq = -1;				
			} else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA)
				&& (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) {
				if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) {
					adv->type = ADV_ISAPNP;
					ADV_OUTB(adv, ADV_REG_IFC,
						 ADV_IFC_INIT_DEFAULT);
				} else {
					adv->type = ADV_ISA;
				}
				maxsegsz = ADV_ISA_MAX_DMA_COUNT;
				maxsize = BUS_SPACE_MAXSIZE_24BIT;
				lowaddr = ADV_ISA_MAX_DMA_ADDR;
				adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED;
				adv->isa_dma_channel =
				    adv_get_isa_dma_channel(adv);
				id->id_drq = adv->isa_dma_channel;
			} else {
				panic("advisaprobe: Unknown card revision\n");
			}

			/*
			 * Allocate a parent dmatag for all tags created
			 * by the MI portions of the advansys driver
			 */
			/* XXX Should be a child of the ISA bus dma tag */ 
			error =
			    bus_dma_tag_create(/*parent*/NULL,
					       /*alignemnt*/0,
					       /*boundary*/0,
					       lowaddr,
					       /*highaddr*/BUS_SPACE_MAXADDR,
					       /*filter*/NULL,
					       /*filterarg*/NULL,
					       maxsize,
					       /*nsegs*/BUS_SPACE_UNRESTRICTED,
					       maxsegsz,
					       /*flags*/0,
					       &adv->parent_dmat); 
 
			if (error != 0) {
				printf("%s: Could not allocate DMA tag - error %d\n",
				       adv_name(adv), error); 
				adv_free(adv); 
				return (0); 
			}

			adv->init_level++;

			if (overrun_buf == NULL) {
				/* Need to allocate our overrun buffer */
				if (bus_dma_tag_create(adv->parent_dmat,
						       /*alignment*/8,
						       /*boundary*/0,
						       ADV_ISA_MAX_DMA_ADDR,
						       BUS_SPACE_MAXADDR,
						       /*filter*/NULL,
						       /*filterarg*/NULL,
						       ADV_OVERRUN_BSIZE,
						       /*nsegments*/1,
						       BUS_SPACE_MAXSIZE_32BIT,
						       /*flags*/0,
						       &overrun_dmat) != 0) {
					adv_free(adv);
					return (0);
        			}
				if (bus_dmamem_alloc(overrun_dmat,
						     (void **)&overrun_buf,
						     BUS_DMA_NOWAIT,
						     &overrun_dmamap) != 0) {
					bus_dma_tag_destroy(overrun_dmat);
					adv_free(adv);
					return (0);
				}
				/* And permanently map it in */  
				bus_dmamap_load(overrun_dmat, overrun_dmamap,
						overrun_buf, ADV_OVERRUN_BSIZE,
                        			adv_map, &overrun_physbase,
						/*flags*/0);
			}

			adv->overrun_physbase = overrun_physbase;
			
			if (adv_init(adv) != 0) {
				adv_free(adv);
				return (0);
			}

			switch (adv->type) {
			case ADV_ISAPNP:
				if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG){
					adv->bug_fix_control
					    |= ADV_BUG_FIX_ASYN_USE_SYN;
					adv->fix_asyn_xfer = ~0;
				}
				/* Fall Through */
			case ADV_ISA:
				adv->max_dma_count = ADV_ISA_MAX_DMA_COUNT;
				adv->max_dma_addr = ADV_ISA_MAX_DMA_ADDR;
				adv_set_isa_dma_settings(adv);
				break;

			case ADV_VL:
				adv->max_dma_count = ADV_VL_MAX_DMA_COUNT;
				adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR;
				break;
			default:
				panic("advisaprobe: Invalid card type\n");
			}
			
			/* Determine our IRQ */
			if (id->id_irq == 0 /* irq ? */)
				id->id_irq = 1 << adv_get_chip_irq(adv);
			else
				adv_set_chip_irq(adv, ffs(id->id_irq) - 1);

			id->id_intr = adv_isa_intr;
			
			/* Mark as probed */
			adv_isa_ioports[port_index] = 0;
			return 1;
		}
	}

	return 0;
}