add: }
context: init_driver(void){	status_t rv;	bigtime_t start;	bool s0cr, s1cr, s2cr;	LOG_CREATE();		LOG(("init_driver\n"));		ASSERT(sizeof(ich_bd) == 8);		rv = probe_device();	if (rv != B_OK) {		LOG(("No supported audio hardware found.\n"));		return B_ERROR;	}	PRINT((VERSION "\n"));	PRINT(("found %s\n", config->name));	PRINT(("IRQ = %ld, NAMBAR = %#lX, NABMBAR = %#lX, MMBAR = %#lX, MBBAR = %#lX\n",config->irq,config->nambar,config->nabmbar,config->mmbar,config->mbbar));	/* before doing anything else, map the IO memory */	rv = map_io_memory();	if (rv != B_OK) {		PRINT(("mapping of memory IO space failed\n"));		return B_ERROR;	}		dump_hardware_regs();		/* do a cold reset */	LOG(("cold reset\n"));	ich_reg_write_32(ICH_REG_GLOB_CNT, 0);	ich_reg_read_32(ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush	snooze(50000); // 50 ms	ich_reg_write_32(ICH_REG_GLOB_CNT, CNT_COLD | CNT_PRIE);	LOG(("cold reset finished\n"));	rv = ich_reg_read_32(ICH_REG_GLOB_CNT);	if ((rv & CNT_COLD) == 0) {		LOG(("cold reset failed\n"));	}	/* detect which codecs are ready */	s0cr = s1cr = s2cr = false;	start = system_time();	do {		rv = ich_reg_read_32(ICH_REG_GLOB_STA);		if (!s0cr && (rv & STA_S0CR)) {			s0cr = true;			LOG(("AC_SDIN0 codec ready after %Ld us\n",(system_time() - start)));		}		if (!s1cr && (rv & STA_S1CR)) {			s1cr = true;			LOG(("AC_SDIN1 codec ready after %Ld us\n",(system_time() - start)));		}		if (!s2cr && (rv & STA_S2CR)) {			s2cr = true;			LOG(("AC_SDIN2 codec ready after %Ld us\n",(system_time() - start)));		}		snooze(50000);	} while ((system_time() - start) < 1000000);	if (!s0cr) {		LOG(("AC_SDIN0 codec not ready\n"));	}	if (!s1cr) {		LOG(("AC_SDIN1 codec not ready\n"));	}	if (!s2cr) {		LOG(("AC_SDIN2 codec not ready\n"));	}	dump_hardware_regs();	if (!s0cr && !s1cr && !s2cr) {		PRINT(("compatible chipset found, but no codec ready!\n"));		unmap_io_memory();		return B_ERROR;	}	if (config->type & TYPE_ICH4) {		/* we are using a ICH4 chipset, and assume that the codec beeing ready		 * is the primary one.		 */		uint8 sdin;		uint16 reset;		uint8 id;		reset = ich_codec_read(0x00);	/* access the primary codec */		if (reset == 0 || reset == 0xFFFF) {			LOG(("primary codec not present\n"));		} //else {			sdin = 0x02 & ich_reg_read_8(ICH_REG_SDM);			id = 0x02 & (ich_codec_read(0x00 + 0x28) >> 14);			LOG(("primary codec id %d is connected to AC_SDIN%d\n", id, sdin));		//}		reset = ich_codec_read(0x80);	/* access the secondary codec */		if (reset == 0 || reset == 0xFFFF) {			LOG(("secondary codec not present\n"));		} //else {			sdin = 0x02 & ich_reg_read_8(ICH_REG_SDM);			id = 0x02 & (ich_codec_read(0x80 + 0x28) >> 14);			LOG(("secondary codec id %d is connected to AC_SDIN%d\n", id, sdin));		//}		reset = ich_codec_read(0x100);	/* access the tertiary codec */		if (reset == 0 || reset == 0xFFFF) {			LOG(("tertiary codec not present\n"));		} //else {			sdin = 0x02 & ich_reg_read_8(ICH_REG_SDM);			id = 0x02 & (ich_codec_read(0x100 + 0x28) >> 14);			LOG(("tertiary codec id %d is connected to AC_SDIN%d\n", id, sdin));		//}				/* XXX this may be wrong */		ich_reg_write_8(ICH_REG_SDM, (ich_reg_read_8(ICH_REG_SDM) & 0x0F) | 0x08 | 0x90);	} else {		/* we are using a pre-ICH4 chipset, that has a fixed mapping of		 * AC_SDIN0 = primary, AC_SDIN1 = secondary codec.		 */		if (!s0cr && s2cr) {			// is is unknown if this really works, perhaps we should better abort here			LOG(("primary codec doesn't seem to be available, using secondary!\n"));			config->codecoffset = 0x80;		}	}	dump_hardware_regs();	/* allocate memory for channel info struct */	chan_pi = (ich_chan *) malloc(sizeof(ich_chan));	chan_po = (ich_chan *) malloc(sizeof(ich_chan));	chan_mc = (ich_chan *) malloc(sizeof(ich_chan));	if (0 == chan_pi || 0 == chan_po || 0 == chan_mc) {		PRINT(("couldn't allocate memory for channel descriptors!\n"));		chan_free_resources();		unmap_io_memory();		return B_ERROR;		}	/* allocate memory for buffer descriptors */	chan_po->bd_area = alloc_mem(&chan_po->bd_log_base, &chan_po->bd_phy_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 po buf desc");	chan_pi->bd_area = alloc_mem(&chan_pi->bd_log_base, &chan_pi->bd_phy_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 pi buf desc");	chan_mc->bd_area = alloc_mem(&chan_mc->bd_log_base, &chan_mc->bd_phy_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 mc buf desc");	/* allocate memory buffers */	chan_po->buffer_area = alloc_mem(&chan_po->buffer_log_base, &chan_po->buffer_phy_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 po buf");	chan_pi->buffer_area = alloc_mem(&chan_pi->buffer_log_base, &chan_pi->buffer_phy_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi buf");	chan_mc->buffer_area = alloc_mem(&chan_mc->buffer_log_base, &chan_mc->buffer_phy_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc buf");	/* allocate memory exported userland buffers */	chan_po->userbuffer_area = alloc_mem(&chan_po->userbuffer_base, NULL, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 po user buf");	chan_pi->userbuffer_area = alloc_mem(&chan_pi->userbuffer_base, NULL, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi user buf");	chan_mc->userbuffer_area = alloc_mem(&chan_mc->userbuffer_base, NULL, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc user buf");	if (  chan_po->bd_area < B_OK || chan_po->buffer_area < B_OK || chan_po->userbuffer_area < B_OK ||		  chan_pi->bd_area < B_OK || chan_pi->buffer_area < B_OK || chan_pi->userbuffer_area < B_OK ||		  chan_mc->bd_area < B_OK || chan_mc->buffer_area < B_OK || chan_mc->userbuffer_area < B_OK) {		PRINT(("couldn't allocate memory for DMA buffers!\n"));		chan_free_resources();		unmap_io_memory();		return B_ERROR;		}	/* allocate all semaphores */	chan_po->buffer_ready_sem = create_sem(0,"po buffer ready");			/* pcm out buffer available */	chan_pi->buffer_ready_sem = create_sem(0,"pi buffer ready");			/* 0 available pcm in buffers */	chan_mc->buffer_ready_sem = create_sem(0,"mc buffer ready");			/* 0 available mic in buffers */		if (chan_po->buffer_ready_sem < B_OK || chan_pi->buffer_ready_sem < B_OK || chan_mc->buffer_ready_sem < B_OK) {		PRINT(("couldn't create semaphores!\n"));		chan_free_resources();		unmap_io_memory();		return B_ERROR;		}	/* setup channel register base address */	chan_pi->regbase = ICH_REG_PI_BASE;	chan_po->regbase = ICH_REG_PO_BASE;	chan_mc->regbase = ICH_REG_MC_BASE;	/* reset all channels */	reset_chan(chan_pi);	reset_chan(chan_po);	reset_chan(chan_mc);	/* init channels */	init_chan(chan_pi);	init_chan(chan_po);	init_chan(chan_mc);	ac97_attach(&config->ac97, ac97_reg_read, ac97_reg_write, NULL);	LOG(("codec vendor id      = %#08x\n", config->ac97->codec_id));	LOG(("codec descripton     = %s\n", config->ac97->codec_info));	LOG(("codec 3d enhancement = %s\n", config->ac97->codec_3d_stereo_enhancement));	/* first test if interrupts are working, on some Laptops they don't work :-( */	if (config->irq != 0 && false == interrupt_test()) {		LOG(("interrupt not working, using a kernel thread for polling\n"));		config->irq = 0; /* don't use interrupts */	}	/* install interrupt or polling thread */	if (config->irq != 0) {		install_io_interrupt_handler(config->irq,ich_int,0,0);	} else {		int_thread_id = spawn_kernel_thread(int_thread, "ich_ac97 interrupt poller", B_REAL_TIME_PRIORITY, 0);		resume_thread(int_thread_id);	}		/* calibrate the clock */	ich_clock_calibrate();		LOG(("init_driver finished!\n"));	return B_OK;}