예제 #1
0
파일: driver.c 프로젝트: mmanley/Antares
static status_t
free_hook (void* cookie)
{
	dp83815_properties_t *data = (dp83815_properties_t *) cookie;

	TRACE(( kDevName " free_hook()\n" ));

	while ( data->Tx.Lock );				/*	wait for any current writes to finish	*/
	while ( data->Rx.Lock );				/*	wait for any current reads to finish	*/

	//Remove interrupt handler
	remove_io_interrupt_handler( data->pcii->u.h0.interrupt_line ,
	                             dp83815_interrupt_hook , cookie );

	m_openmask &= ~(1L << data->device_id);

	free_resources(data);					/*	unblock waiting threads		*/

	//Finally, free the cookie
	free( data );

	//Put the pci module
	put_module( B_PCI_MODULE_NAME );

	return B_OK;
}
예제 #2
0
void
bus_teardown_intr(device_t dev, struct resource *res, void *tag)
{
	struct int_tag *int_tag = (struct int_tag *) tag;
	remove_io_interrupt_handler(int_tag->irq, int_tag->int_func, int_tag->cookie);
	free(int_tag);
}
예제 #3
0
/**
 * Removes IRQ for VMMDev.
 *
 * @param   pvState  Opaque pointer to the state info structure.
 */
static void VBoxGuestHaikuRemoveIRQ(void *pvState)
{
    struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
    AssertPtr(pState);

    remove_io_interrupt_handler(pState->iIrqResId, VBoxGuestHaikuISR, pState);
}
예제 #4
0
파일: device.c 프로젝트: luciang/haiku
status_t
device_close(void *data)
{
	struct sis_info *info;

	if (checkDeviceInfo(info = data) != B_OK)
		return EINVAL;

	info->cookieMagic = SiS_FREE_COOKIE_MAGIC;

	// cancel timer
	cancel_timer(&info->timer);

	// remove & disable interrupt
	sis900_disableInterrupts(info);
	remove_io_interrupt_handler(info->pciInfo->u.h0.interrupt_line, sis900_interrupt, info);

	// disable the transmitter's and receiver's state machine
	write32(info->registers + SiS900_MAC_COMMAND,
		SiS900_MAC_CMD_Rx_DISABLE | SiS900_MAC_CMD_Tx_DISABLE);

	delete_sem(info->rxSem);
	delete_sem(info->txSem);

#ifdef EXCESSIVE_DEBUG
	delete_sem(gIOLock);
#endif

	return B_OK;
}
예제 #5
0
void
intel_extreme_uninit(intel_info &info)
{
    CALLED();

    if (!info.fake_interrupts && info.shared_info->vblank_sem > 0) {
        // disable interrupt generation
        write16(info, find_reg(info, INTEL_INTERRUPT_ENABLED), 0);
        write16(info, find_reg(info, INTEL_INTERRUPT_MASK), ~0);

        remove_io_interrupt_handler(info.irq, intel_interrupt_handler, &info);

        if (info.use_msi && gPCIx86Module != NULL) {
            gPCIx86Module->disable_msi(info.pci->bus,
                                       info.pci->device, info.pci->function);
            gPCIx86Module->unconfigure_msi(info.pci->bus,
                                           info.pci->device, info.pci->function);
        }
    }

    gGART->unmap_aperture(info.aperture);

    delete_area(info.registers_area);
    delete_area(info.shared_area);
}
void
arch_debug_remove_interrupt_handler(uint32 line)
{
    if (line != INT_PS2_KEYBOARD || !sKeyboardHandlerInstalled)
        return;

    remove_io_interrupt_handler(INT_PS2_KEYBOARD, &debug_keyboard_interrupt,
                                NULL);
    sKeyboardHandlerInstalled = false;
}
예제 #7
0
파일: driver.c 프로젝트: luciang/haiku
static status_t
free_hook(void* dev)
{
	device_info *di = (device_info *)dev;
	shared_info	*si = di->si;
	vuint32 *regs = di->regs;

	/* lock the driver */
	AQUIRE_BEN(pd->kernel);

	/* if opened multiple times, decrement the open count and exit */
	if (di->is_open > 1)
		goto unlock_and_exit;

	/* disable and clear any pending interrupts */
	//fixme:
	//distinquish between crtc1/crtc2 once all heads get seperate driver instances!
	disable_vbi_all(regs);

	if (si->ps.int_assigned) {
		/* remove interrupt handler */
		remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, nv_interrupt, di);

		/* delete the semaphores, ignoring any errors ('cause the owning
		   team may have died on us) */
		delete_sem(si->vblank);
		si->vblank = -1;
	}

	/* free regs and framebuffer areas */
	unmap_device(di);

	/* clean up our aligned DMA area */
	delete_area(si->dma_area);
	si->dma_area = -1;
	si->dma_buffer = NULL;

	/* clean up our unaligned DMA area */
	delete_area(si->unaligned_dma_area);
	si->unaligned_dma_area = -1;
	si->dma_buffer_pci = NULL;

	/* clean up our shared area */
	delete_area(di->shared_area);
	di->shared_area = -1;
	di->si = NULL;

unlock_and_exit:
	/* mark the device available */
	di->is_open--;
	/* unlock the driver */
	RELEASE_BEN(pd->kernel);
	/* all done */
	return B_OK;
}
예제 #8
0
파일: b57um.c 프로젝트: luciang/haiku
static status_t
b57_free(void *cookie)
{
	struct be_b57_dev *pUmDevice = (struct be_b57_dev *)(cookie);

	if (cookie == NULL)
		return B_OK;

	remove_io_interrupt_handler(pUmDevice->pci_data.u.h1.interrupt_line, b57_interrupt, cookie);
	return B_OK;
}
예제 #9
0
static void
ice_1712_shutdown(ice1712 *ice)
{
	delete_sem(ice->buffer_ready_sem);

	remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);

	if (ice->mem_id_pb != B_ERROR)
		delete_area(ice->mem_id_pb);

	if (ice->mem_id_rec != B_ERROR)
		delete_area(ice->mem_id_rec);

	codec_write(ice, AK45xx_RESET_REGISTER, 0x00);
}
예제 #10
0
파일: hpet.cpp 프로젝트: AmirAbrams/haiku
status_t
hpet_close(void* cookie)
{	
	if (sHPETRegs == NULL)
		return B_NO_INIT;

	atomic_add(&sOpenCount, -1);

	hpet_timer_cookie* hpetCookie = (hpet_timer_cookie*)cookie;

	dprintf("hpet_close (%d)\n", hpetCookie->number);
	hpet_clear_hardware_timer(&sHPETRegs->timer[hpetCookie->number]);
	remove_io_interrupt_handler(hpetCookie->irq, &hpet_timer_interrupt, hpetCookie);

	return B_OK;
}
예제 #11
0
파일: b57um.c 프로젝트: luciang/haiku
static status_t
b57_open(const char *name, uint32 flags, void **cookie)
{
	struct be_b57_dev *pDevice = NULL;
	int i;

	*cookie = NULL;
	for (i = 0; i < cards_found; i++) {
		if (strcmp(dev_list[i],name) == 0) {
			*cookie = pDevice = &be_b57_dev_cards[i];
			break;
		}
	}

	if (*cookie == NULL)
		return B_FILE_NOT_FOUND;

	if (atomic_or(&pDevice->opened, 1)) {
		*cookie = pDevice = NULL;
		return B_BUSY;
	}

	install_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line,
		b57_interrupt, *cookie, 0);
	if (LM_InitializeAdapter(&pDevice->lm_dev) != LM_STATUS_SUCCESS) {
		atomic_and(&pDevice->opened,0);
		remove_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line, b57_interrupt, *cookie);
		*cookie = NULL;
		return B_ERROR;
	}

	/*QQ_InitQueue(&pDevice->rx_out_of_buf_q.Container,
        MAX_RX_PACKET_DESC_COUNT);*/

	//pDevice->lm_dev.PhyCrcCount = 0;
	LM_EnableInterrupt(&pDevice->lm_dev);

	dprintf("Broadcom 57xx adapter successfully inited at %s:\n", name);
	dprintf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
		pDevice->lm_dev.NodeAddress[0], pDevice->lm_dev.NodeAddress[1],
		pDevice->lm_dev.NodeAddress[2], pDevice->lm_dev.NodeAddress[3],
		pDevice->lm_dev.NodeAddress[4], pDevice->lm_dev.NodeAddress[5]);
	dprintf("PCI Data: 0x%08x\n", pDevice->pci_data.u.h0.base_registers[0]);
	dprintf("IRQ: %d\n", pDevice->pci_data.u.h0.interrupt_line);

	return B_OK;
}
예제 #12
0
static status_t
device_free(void* dev)
{
	DeviceInfo& di = *((DeviceInfo*)dev);
	SharedInfo& si = *(di.sharedInfo);
	pci_info& pciInfo = di.pciInfo;

	TRACE("enter device_free()\n");

	gLock.Acquire();		// lock driver

	// If opened multiple times, merely decrement the open count and exit.

	if (di.openCount <= 1) {
		DisableVBI();		// disable & clear any pending interrupts

		if (si.bInterruptAssigned) {
			remove_io_interrupt_handler(pciInfo.u.h0.interrupt_line,
				InterruptHandler, &di);
		}

		// Delete the semaphores, ignoring any errors because the owning team
		// may have died.
		if (si.vertBlankSem >= 0)
			delete_sem(si.vertBlankSem);
		si.vertBlankSem = -1;

		UnmapDevice(di);	// free regs and frame buffer areas

		delete_area(di.sharedArea);
		di.sharedArea = -1;
		di.sharedInfo = NULL;
	}

	if (di.openCount > 0)
		di.openCount--;		// mark device available

	gLock.Release();	// unlock driver

	TRACE("exit device_free() openCount: %ld\n", di.openCount);
	return B_OK;
}
예제 #13
0
파일: device.c 프로젝트: luciang/haiku
static status_t
wb840_close(void* cookie)
{
	wb_device *device = (wb_device *)cookie;
	
	LOG((DEVICE_NAME ": close()\n"));
	
	cancel_timer(&device->timer);
		
	wb_stop(device);
	
	write32(device->reg_base + WB_TXADDR, 0x00000000);
	write32(device->reg_base + WB_RXADDR, 0x00000000);

	wb_disable_interrupts(device);	
	remove_io_interrupt_handler(device->irq, wb_interrupt, device);
	
	delete_sem(device->rxSem);
	delete_sem(device->txSem);
			
	return B_OK;
}
예제 #14
0
파일: driver.c 프로젝트: DonCN/haiku
/* -----------
	free_hook - close down the device
----------- */
static status_t
free_hook (void* dev) {
	device_info *di = (device_info *)dev;
	shared_info	*si = di->si;
	vuint32 *regs = di->regs;

	/* lock the driver */
	AQUIRE_BEN(pd->kernel);

	/* if opened multiple times, decrement the open count and exit */
	if (di->is_open > 1)
		goto unlock_and_exit;

	/* disable and clear any pending interrupts */
	disable_vbi(regs);

	/* remove interrupt handler */
	remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, eng_interrupt, di);

	/* delete the semaphores, ignoring any errors ('cause the owning team may have died on us) */
	delete_sem(si->vblank);
	si->vblank = -1;

	/* free regs and framebuffer areas */
	unmap_device(di);

	/* clean up our shared area */
	delete_area(di->shared_area);
	di->shared_area = -1;
	di->si = NULL;

unlock_and_exit:
	/* mark the device available */
	di->is_open--;
	/* unlock the driver */
	RELEASE_BEN(pd->kernel);
	/* all done */
	return B_OK;
}
예제 #15
0
파일: driver.c 프로젝트: looncraz/haiku
/*
 * et6000FreeHook - close down the device
 */
static status_t et6000FreeHook(void* dev) {
ET6000DeviceInfo *di = (ET6000DeviceInfo *)dev;
ET6000SharedInfo *si = di->si;

    ddprintf(("SKD et6000FreeHook() begins...\n"));
    /* lock the driver */
    AQUIRE_BEN(pd->kernel);

    /* if opened multiple times, decrement the open count and exit */
    if (di->isOpen > 1)
        goto unlock_and_exit;

    /* Clear any pending interrupts and disable interrupts. */
    et6000aclReadInterruptClear(si->mmRegs);
    et6000aclWriteInterruptClear(si->mmRegs);
    et6000aclMasterInterruptDisable(si->mmRegs);

    /* Remove the interrupt handler */
    remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, et6000Interrupt, di);

    /* free framebuffer area */
    et6000UnmapDevice(di);

    /* clean up our shared area */
    delete_area(di->sharedArea);
    di->sharedArea = -1;
    di->si = NULL;

unlock_and_exit:
    /* mark the device available */
    di->isOpen--;
    /* unlock the driver */
    RELEASE_BEN(pd->kernel);
    ddprintf(("SKD et6000FreeHook() ends.\n"));
    /* all done */
    return B_OK;
}
예제 #16
0
파일: device.c 프로젝트: luciang/haiku
static status_t
wb840_open(const char *name, uint32 flags, void** cookie)
{
	char *deviceName = NULL;
	int32 i;
	int32 mask;
	struct wb_device *data;
	status_t status;
	
	LOG((DEVICE_NAME ": open()\n"));
	
	for (i = 0; (deviceName = gDevNameList[i]) != NULL; i++) {
		if (!strcmp(name, deviceName))
			break;
	}		
	
	if (deviceName == NULL) {
		LOG(("invalid device name"));
		return EINVAL;
	}
	
	// There can be only one access at time
	mask = 1L << i;
	if (atomic_or(&sOpenMask, mask) & mask)
		return B_BUSY;
	
	// Allocate a wb_device structure
	if (!(data = (wb_device *)malloc(sizeof(wb_device)))) {
		sOpenMask &= ~(1L << i);
		return B_NO_MEMORY;
	}
	
	memset(data, 0, sizeof(wb_device));
	
	*cookie = data;

#ifdef DEBUG
	load_driver_symbols("wb840");
#endif

	data->devId = i;
	data->pciInfo = gDevList[i];
	data->deviceName = gDevNameList[i];
	data->blockFlag = 0;
	data->reg_base = data->pciInfo->u.h0.base_registers[0];	
	data->wb_cachesize = gPci->read_pci_config(data->pciInfo->bus, data->pciInfo->device,
			data->pciInfo->function, PCI_line_size, sizeof (PCI_line_size)) & 0xff;
		
	wb_read_eeprom(data, &data->MAC_Address, 0, 3, false);
	
	status = wb_create_semaphores(data);
	if (status < B_OK) {
		LOG((DEVICE_NAME ": Couldn't create semaphores\n"));
		goto err;
	}
		
	status = wb_stop(data);
	if (status < B_OK) {
		LOG((DEVICE_NAME": Can't stop device\n"));
		goto err1;
	}
			
	status = wb_initPHYs(data);
	if (status < B_OK) {
		LOG((DEVICE_NAME": Can't init PHYs\n"));
		goto err1;
	}
		
	wb_init(data);
		
	/* Setup interrupts */
	data->irq = data->pciInfo->u.h0.interrupt_line;
	status = install_io_interrupt_handler(data->irq, wb_interrupt, data, 0);
	if (status < B_OK) {
		LOG((DEVICE_NAME
			" can't install interrupt handler: %s\n", strerror(status)));
		goto err1;		
	}
	
	LOG(("Interrupts installed at irq line %x\n", data->irq));
		
	status = wb_create_rings(data);
	if (status < B_OK) {
		LOG((DEVICE_NAME": can't create ring buffers\n"));
		goto err2;
	}
	
	wb_enable_interrupts(data);	
	
	WB_SETBIT(data->reg_base + WB_NETCFG, WB_NETCFG_RX_ON);
	write32(data->reg_base + WB_RXSTART, 0xFFFFFFFF);
	WB_SETBIT(data->reg_base + WB_NETCFG, WB_NETCFG_TX_ON);
	
	add_timer(&data->timer, wb_tick, 1000000LL, B_PERIODIC_TIMER);
		
	return B_OK; // Everything after this line is an error
		
err2:
	remove_io_interrupt_handler(data->irq, wb_interrupt, data);
	
err1:
	wb_delete_semaphores(data);
	
err:			
	sOpenMask &= ~(1L << i);
	
	free(data);	
	LOG(("wb840: Open Failed\n"));
	
	return status;
}
예제 #17
0
static status_t
ice1712_setup(ice1712 *ice)
{
	int result, i;
	uint8 reg8 = 0;
	uint16 mute;

	ice->irq			= ice->info.u.h0.interrupt_line;
	ice->Controller		= ice->info.u.h0.base_registers[0];
	ice->DDMA			= ice->info.u.h0.base_registers[1];
	ice->DMA_Path		= ice->info.u.h0.base_registers[2];
	ice->Multi_Track	= ice->info.u.h0.base_registers[3];

	// Soft Reset
	write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x81);
	snooze(200000);
	write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x01);
	snooze(200000);

	result = read_eeprom(ice, ice->eeprom_data);

/*	TRACE("EEprom -> ");
	for (i = 0; i < 32; i++)
		TRACE("%x, ", eeprom_data[i]);
	TRACE("<- EEprom\n");*/

	write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01);

	//Write all configurations register from EEProm
	ice->info.device_id = ice->eeprom_data[E2PROM_MAP_SUBVENDOR_HIGH] << 8
		| ice->eeprom_data[E2PROM_MAP_SUBVENDOR_LOW];
	ice->info.vendor_id = ice->eeprom_data[E2PROM_MAP_SUBDEVICE_HIGH] << 8
		| ice->eeprom_data[E2PROM_MAP_SUBDEVICE_LOW];
	ice->product = ice->info.vendor_id << 16 | ice->info.device_id;
	TRACE("Product ID : 0x%x\n", ice->product);

	write_cci_uint8(ice, CCI_GPIO_WRITE_MASK,
		ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
	write_cci_uint8(ice, CCI_GPIO_DATA,
		ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
	write_cci_uint8(ice, CCI_GPIO_DIRECTION_CONTROL,
		ice->eeprom_data[E2PROM_MAP_GPIODIR]);

	TRACE("CCI_GPIO_WRITE_MASK : 0x%x\n",
		ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
	TRACE("CCI_GPIO_DATA : 0x%x\n",
		ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
	TRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n",
		ice->eeprom_data[E2PROM_MAP_GPIODIR]);


	//Write Configuration in the PCI configuration Register
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]);
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x61, 1, ice->eeprom_data[E2PROM_MAP_ACL]);
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x62, 1, ice->eeprom_data[E2PROM_MAP_I2S]);
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x63, 1, ice->eeprom_data[E2PROM_MAP_SPDIF]);

	TRACE("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG]);
	reg8 = ice->eeprom_data[E2PROM_MAP_CONFIG];
	//Bits signification for E2PROM_MAP_CONFIG Byte
	//
	// 8   7   6   5   4   3   2   1   0
	//           |-D-|-C-|---B---|---A---
	//
	// D : MPU401 number minus 1
	// C : AC'97
	// B : Stereo ADC number minus 1 (=> 1 to 4)
	// A : Stereo DAC number minus 1 (=> 1 to 4)

	ice->config.nb_DAC = ((reg8 & 0x03) + 1) * 2;
	reg8 >>= 2;
	ice->config.nb_ADC = ((reg8 & 0x03) + 1) * 2;
	reg8 >>= 2;

	if ((reg8 & 0x01) != 0) {//Consumer AC'97 Exist
		TRACE("Consumer AC'97 does exist\n");
		//For now do nothing
/*		write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x40);
		snooze(10000);
		write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x00);
		snooze(20000);
*/	} else {
		TRACE("Consumer AC'97 does NOT exist\n");
	}
	reg8 >>= 1;
	ice->config.nb_MPU401 = (reg8 & 0x1) + 1;

	if (ice->config.nb_MPU401 > 0) {
		sprintf(ice->midi_interf[0].name, "midi/ice1712/%ld/1",
			ice - cards + 1);

		(*mpu401->create_device)(ice->Controller + CCS_MIDI_1_DATA,
			&ice->midi_interf[0].mpu401device,
			0x14121712,
			ice_1712_midi_interrupt_op,
			&ice->midi_interf[0]);

		names[num_names++] = ice->midi_interf[0].name;
		ice->midi_interf[0].card = ice;
		ice->midi_interf[0].int_mask = CCS_INTERRUPT_MIDI_1;
	}

	if (ice->config.nb_MPU401 > 1) {
		sprintf(ice->midi_interf[1].name, "midi/ice1712/%ld/2",
			ice - cards + 1);

		(*mpu401->create_device)(ice->Controller + CCS_MIDI_2_DATA,
			&ice->midi_interf[1].mpu401device,
			0x14121712,
			ice_1712_midi_interrupt_op,
			&ice->midi_interf[1]);

		names[num_names++] = ice->midi_interf[1].name;
		ice->midi_interf[1].card = ice;
		ice->midi_interf[1].int_mask = CCS_INTERRUPT_MIDI_2;
	}

	TRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]);
	ice->config.spdif = ice->eeprom_data[E2PROM_MAP_SPDIF];

	switch (ice->product) {
		case ICE1712_SUBDEVICE_DELTA66 :
		case ICE1712_SUBDEVICE_DELTA44 :
			ice->CommLines.clock = DELTA66_CLK;
			ice->CommLines.data_in = 0;
			ice->CommLines.data_out = DELTA66_DOUT;
			ice->CommLines.cs_mask = DELTA66_CLK | DELTA66_DOUT
				| DELTA66_CODEC_CS_0 | DELTA66_CODEC_CS_1;
			break;
		case ICE1712_SUBDEVICE_DELTA410 :
		case ICE1712_SUBDEVICE_AUDIOPHILE_2496 :
		case ICE1712_SUBDEVICE_DELTADIO2496 :
			ice->CommLines.clock = AP2496_CLK;
			ice->CommLines.data_in = AP2496_DIN;
			ice->CommLines.data_out = AP2496_DOUT;
			ice->CommLines.cs_mask = AP2496_CLK | AP2496_DIN
				| AP2496_DOUT | AP2496_SPDIF_CS | AP2496_CODEC_CS;
			break;
		case ICE1712_SUBDEVICE_DELTA1010 :
		case ICE1712_SUBDEVICE_DELTA1010LT :
			ice->CommLines.clock = DELTA1010LT_CLK;
			ice->CommLines.data_in = DELTA1010LT_DIN;
			ice->CommLines.data_out = DELTA1010LT_DOUT;
			ice->CommLines.cs_mask = DELTA1010LT_CLK | DELTA1010LT_DIN
				| DELTA1010LT_DOUT | DELTA1010LT_CS_NONE;
			break;
		case ICE1712_SUBDEVICE_VX442 :
			ice->CommLines.clock = VX442_CLK;
			ice->CommLines.data_in = VX442_DIN;
			ice->CommLines.data_out = VX442_DOUT;
			ice->CommLines.cs_mask = VX442_SPDIF_CS | VX442_CODEC_CS_0
				| VX442_CODEC_CS_1;
			break;
	}

	sprintf(ice->name, "%s/%ld", HMULTI_AUDIO_DEV_PATH, ice - cards + 1);
	names[num_names++] = ice->name;
	names[num_names] = NULL;

	ice->buffer_ready_sem = create_sem(0, "Buffer Exchange");
	if (ice->buffer_ready_sem < B_OK) {
		return ice->buffer_ready_sem;
	}

//	TRACE("installing interrupt : %0x\n", ice->irq);
	install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0);

	ice->mem_id_pb = alloc_mem(&ice->phys_addr_pb, &ice->log_addr_pb,
								PLAYBACK_BUFFER_TOTAL_SIZE,
								"playback buffer");
	if (ice->mem_id_pb < B_OK) {
		remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
		delete_sem(ice->buffer_ready_sem);
		return ice->mem_id_pb;
	}

	ice->mem_id_rec = alloc_mem(&ice->phys_addr_rec, &ice->log_addr_rec,
								RECORD_BUFFER_TOTAL_SIZE,
								"record buffer");
	if (ice->mem_id_rec < B_OK) {
		remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
		delete_sem(ice->buffer_ready_sem);
		delete_area(ice->mem_id_pb);
		return(ice->mem_id_rec);
	}

	memset(ice->log_addr_pb, 0, PLAYBACK_BUFFER_TOTAL_SIZE);
	memset(ice->log_addr_rec, 0, RECORD_BUFFER_TOTAL_SIZE);

	ice->sampling_rate = 0x08;
	ice->buffer = 0;
	ice->frames_count = 0;
	ice->buffer_size = MAX_BUFFER_FRAMES;

	ice->total_output_channels = ice->config.nb_DAC;
	if (ice->config.spdif & SPDIF_OUT_PRESENT)
		ice->total_output_channels += 2;

	ice->total_input_channels = ice->config.nb_ADC + 2;
	if (ice->config.spdif & SPDIF_IN_PRESENT)
		ice->total_input_channels += 2;

	//Write bits in the GPIO
	write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->CommLines.cs_mask));
	//Deselect CS
	write_cci_uint8(ice, CCI_GPIO_DATA, ice->CommLines.cs_mask);

	//Set the rampe volume to a faster one
	write_mt_uint16(ice, MT_VOLUME_CONTROL_RATE, 0x01);

	//All Analog outputs from DMA
	write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT,	0x0000);
	//All Digital output from DMA
	write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT,	0x0000);

	//Just to route all input to all output
//	write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT,	0xAAAA);
//	write_mt_uint32(ice, MT_CAPTURED_DATA,	0x76543210);

	//Just to route SPDIF Input to DAC 0
//	write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT,	0xAAAF);
//	write_mt_uint32(ice, MT_CAPTURED_DATA,	0x76543280);

	//Mute all input
	mute = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
	for (i = 0; i < 2 * ICE1712_HARDWARE_VOLUME; i++) {
		write_mt_uint8(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, i);
		write_mt_uint16(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, mute);
	}

	//Unmask Interrupt
	write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x41);

	reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK);
	TRACE("-----CCS----- = %x\n", reg8);
	write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0xEF);

/*	reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK);
	TRACE("-----DS_DMA----- = %x\n", reg16);
	write_ds_uint16(ice, DS_DMA_INT_MASK, 0x0000);
*/
	reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS);
	TRACE("-----MT_DMA----- = %x\n", reg8);
	write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, 0x00);

	return B_OK;
};