Пример #1
0
static status_t
my_transfer_data(my_device *device, bool directionIn, void *data,
	size_t dataLength)
{
	status_t result = gUSBModule->queue_bulk(directionIn ? device->bulk_in
		: device->bulk_out, data, dataLength, my_callback, device);
	if (result != B_OK) {
		TRACE_ALWAYS("failed to queue data transfer\n");
		return result;
	}

	do {
		bigtime_t timeout = directionIn ? 500000 : 500000;
		result = acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT,
			timeout);
		if (result == B_TIMED_OUT) {
			// Cancel the transfer and collect the sem that should now be
			// released through the callback on cancel. Handling of device
			// reset is done in usb_printer_operation() when it detects that
			// the transfer failed.
			gUSBModule->cancel_queued_transfers(directionIn ? device->bulk_in
				: device->bulk_out);
			acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT, 0);
		}
	} while (result == B_INTERRUPTED);

	if (result != B_OK) {
		TRACE_ALWAYS("acquire_sem failed while waiting for data transfer\n");
		return result;
	}

	return B_OK;
}
Пример #2
0
bool
MultiLocker::WriteLock()
{
#if TIMING
    bigtime_t start = system_time();
#endif

    bool locked = false;

    if (fInit == B_OK) {
        uint32 stack_base = 0;
        thread_id thread = -1;

        if (IsWriteLocked(&stack_base, &thread)) {
            //already the writer - increment the nesting count
            fWriterNest++;
            locked = true;
        } else {
            //new writer acquiring the lock
            if (atomic_add(&fLockCount, 1) >= 1) {
                //another writer in the lock - acquire the semaphore
                locked = (acquire_sem_etc(fWriterLock, 1, B_DO_NOT_RESCHEDULE,
                                          B_INFINITE_TIMEOUT) == B_OK);
            } else locked = true;

            if (locked) {
                //new holder of the lock

                //decrement fReadCount by a very large number
                //this will cause new readers to block on fReadSem
                int32 readers = atomic_add(&fReadCount, -MAX_READERS);

                if (readers > 0) {
                    //readers hold the lock - acquire fWriteSem
                    locked = (acquire_sem_etc(fWriteSem, readers, B_DO_NOT_RESCHEDULE,
                                              B_INFINITE_TIMEOUT) == B_OK);
                }
                if (locked) {
                    ASSERT(fWriterThread == -1);
                    //record thread information
                    fWriterThread = thread;
                    fWriterStackBase = stack_base;
                }
            }
        }
    }

#if TIMING
    bigtime_t end = system_time();
    wl_time += (end - start);
    wl_count++;
#endif

    return locked;
}
Пример #3
0
status_t
RemoteDrawingEngine::ReadBitmap(ServerBitmap* bitmap, bool drawCursor,
	BRect bounds)
{
	if (_AddCallback() != B_OK)
		return B_UNSUPPORTED;

	RemoteMessage message(NULL, fHWInterface->SendBuffer());

	message.Start(RP_READ_BITMAP);
	message.Add(fToken);
	message.Add(bounds);
	message.Add(drawCursor);
	if (message.Flush() != B_OK)
		return B_UNSUPPORTED;

	status_t result;
	do {
		result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT,
			100 * 1000 * 1000);
	} while (result == B_INTERRUPTED);

	if (result != B_OK)
		return result;

	BBitmap* read = fReadBitmapResult;
	if (read == NULL)
		return B_UNSUPPORTED;

	result = bitmap->ImportBits(read->Bits(), read->BitsLength(),
		read->BytesPerRow(), read->ColorSpace());
	delete read;
	return result;
}
Пример #4
0
BPoint
RemoteDrawingEngine::DrawString(const char* string, int32 length,
	const BPoint* offsets)
{
	// Guaranteed to have at least one point.
	RemoteMessage message(NULL, fHWInterface->SendBuffer());

	message.Start(RP_DRAW_STRING_WITH_OFFSETS);
	message.Add(fToken);
	message.AddString(string, length);
	message.AddList(offsets, UTF8CountChars(string, length));

	status_t result = _AddCallback();
	if (message.Flush() != B_OK)
		return offsets[0];

	if (result != B_OK)
		return offsets[0];

	do {
		result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT,
			1 * 1000 * 1000);
	} while (result == B_INTERRUPTED);

	if (result != B_OK)
		return offsets[0];

	return fDrawStringResult;
}
Пример #5
0
BPoint
RemoteDrawingEngine::DrawString(const char* string, int32 length,
	const BPoint& point, escapement_delta* delta)
{
	RemoteMessage message(NULL, fHWInterface->SendBuffer());

	message.Start(RP_DRAW_STRING);
	message.Add(fToken);
	message.Add(point);
	message.AddString(string, length);
	message.Add(delta != NULL);
	if (delta != NULL)
		message.AddList(delta, length);

	status_t result = _AddCallback();
	if (message.Flush() != B_OK)
		return point;

	if (result != B_OK)
		return point;

	do {
		result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT,
			1 * 1000 * 1000);
	} while (result == B_INTERRUPTED);

	if (result != B_OK)
		return point;

	return fDrawStringResult;
}
Пример #6
0
static status_t
low_resource_manager(void*)
{
	bigtime_t timeout = kLowResourceInterval;
	while (true) {
		int32 state = low_resource_state_no_update(B_ALL_KERNEL_RESOURCES);
		if (state != B_LOW_RESOURCE_CRITICAL) {
			acquire_sem_etc(sLowResourceWaitSem, 1, B_RELATIVE_TIMEOUT,
				timeout);
		}

		RecursiveLocker _(&sLowResourceLock);

		compute_state();
		state = low_resource_state_no_update(B_ALL_KERNEL_RESOURCES);

		TRACE(("low_resource_manager: state = %ld, %ld free pages, %lld free "
			"memory, %lu free semaphores\n", state, vm_page_num_free_pages(),
			vm_available_not_needed_memory(),
			sem_max_sems() - sem_used_sems()));

		if (state < B_LOW_RESOURCE_NOTE)
			continue;

		call_handlers(sLowResources);

		if (state == B_LOW_RESOURCE_WARNING)
			timeout = kWarnResourceInterval;
		else
			timeout = kLowResourceInterval;

		sLowResourceWaiterCondition.NotifyAll();
	}
	return 0;
}
Пример #7
0
static status_t
read_keyboard_packet(at_kbd_io *packet)
{
	status_t status;

	TRACE("ps2: read_keyboard_packet: enter\n");

	status = acquire_sem_etc(sKeyboardSem, 1, B_CAN_INTERRUPT, 0);
	if (status < B_OK)
		return status;

	if (!ps2_device[PS2_DEVICE_KEYB].active) {
		TRACE("ps2: read_keyboard_packet, Error device no longer active\n");
		return B_ERROR;
	}

	if (packet_buffer_read(sKeyBuffer, (uint8 *)packet, sizeof(*packet)) == 0) {
		TRACE("ps2: read_keyboard_packet, Error reading packet: %s\n",
			strerror(status));
		return B_ERROR;
	}

	TRACE("ps2: read_keyboard_packet: scancode: %x, keydown: %s\n",
		packet->scancode, packet->is_keydown ? "true" : "false");

	return B_OK;
}
Пример #8
0
void
wait_for_vblank(void)
{
	acquire_sem_etc(gInfo->shared_info->vblank_sem, 1, B_RELATIVE_TIMEOUT, 25000);
		// With the output turned off via DPMS, we might not get any interrupts anymore
		// that's why we don't wait forever for it.
}
Пример #9
0
/* ----------
	acpi_namespace_read - handle read() calls
----- */
static status_t
acpi_namespace_read(void *_cookie, off_t position, void *buf, size_t* num_bytes)
{
	acpi_ns_device_info *device = (acpi_ns_device_info *)_cookie;
	RingBuffer &ringBuffer = *device->buffer;

	if (!ringBuffer.Lock()) {
		*num_bytes = 0;
		return B_ERROR;
	}

	if (ringBuffer.ReadableAmount() == 0) {
		ringBuffer.Unlock();
		status_t status = acquire_sem_etc(device->read_sem, 1, B_CAN_INTERRUPT, 0);
		if (status != B_OK && status != B_BAD_SEM_ID) {
			*num_bytes = 0;
			return status;
		}
		if (!ringBuffer.Lock()) {
			*num_bytes = 0;
			return B_ERROR;
		}
	}

	*num_bytes = ringBuffer.Read(buf, *num_bytes);
	ringBuffer.Unlock();

	return B_OK;
}
Пример #10
0
status_t
UnixEndpoint::Accept(net_socket **_acceptedSocket)
{
	TRACE("[%ld] %p->UnixEndpoint::Accept()\n", find_thread(NULL), this);

	bigtime_t timeout = absolute_timeout(socket->receive.timeout);
	if (gStackModule->is_restarted_syscall())
		timeout = gStackModule->restore_syscall_restart_timeout();
	else
		gStackModule->store_syscall_restart_timeout(timeout);

	UnixEndpointLocker locker(this);

	status_t error;
	do {
		locker.Unlock();

		error = acquire_sem_etc(fAcceptSemaphore, 1,
			B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, timeout);
		if (error < B_OK)
			RETURN_ERROR(error);

		locker.Lock();
		error = gSocketModule->dequeue_connected(socket, _acceptedSocket);
	} while (error != B_OK);

	if (error == B_TIMED_OUT && timeout == 0) {
		// translate non-blocking timeouts to the correct error code
		error = B_WOULD_BLOCK;
	}

	RETURN_ERROR(error);
}
Пример #11
0
status_t
Device::_MultiBufferExchange(multi_buffer_info* Info)
{
	for (int i = 0; i < fStreams.Count(); i++) {
		if (!fStreams[i]->IsRunning()) {
			fStreams[i]->Start();
		}
	}

	TRACE_ALWAYS("Exchange!\n");
	snooze(1000000);
	return B_OK;

	status_t status = B_ERROR;
	bool anyBufferProcessed = false;
	for (int i = 0; i < fStreams.Count() && !anyBufferProcessed; i++) {
		status = acquire_sem_etc(fBuffersReadySem, 1,
							B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000);
		if (status == B_TIMED_OUT) {
			TRACE_ALWAYS("Timeout during buffers exchange.\n");
			break;
		}

		anyBufferProcessed = fStreams[i]->ExchangeBuffer(Info);
		status = anyBufferProcessed ? B_OK : B_ERROR;
	}

	return status;
}
Пример #12
0
status_t
BBufferGroup::ReclaimAllBuffers()
{
	CALLED();
	if (fInitError != B_OK)
		return B_NO_INIT;

	// because additional BBuffers might get added to this group betweeen
	// acquire and release
	int32 count = fBufferCount;

	if (count < 0)
		return B_BAD_VALUE;
	if (count == 0)
		return B_OK;

	// we need to wait until all BBuffers belonging to this group are reclaimed.
	// this has happened when the "fReclaimSem" can be aquired "fBufferCount"
	// times

	status_t status;
	do {
		status = acquire_sem_etc(fReclaimSem, count, 0, 0);
	} while (status == B_INTERRUPTED);

	if (status != B_OK)
		return status;

	// we need to release the "fReclaimSem" now, else we would block
	// requesting of new buffers

	return release_sem_etc(fReclaimSem, count, 0);
}
Пример #13
0
// copy from graphics memory to other memory via DMA
// 	src		- offset in graphics mem
//	target	- target address
//	size	- number of bytes to copy
//	lock_mem - true, if memory is not locked
//	contiguous - true, if memory is physically contiguous (implies lock_mem=false)
status_t Radeon_DMACopy( 
	device_info *di, uint32 src, char *target, size_t size, bool lock_mem, bool contiguous )
{
	status_t res;
	
	/*SHOW_FLOW( 0, "src=%ld, target=%p, size=%ld, lock_mem=%d, contiguous=%d",
		src, target, size, lock_mem, contiguous );*/
	
	res =  Radeon_PrepareDMA( di, src, target, size, lock_mem, contiguous );
	if( res != B_OK )
		return res;
		
	//SHOW_FLOW0( 0, "2" );

	OUTREG( di->regs, RADEON_DMA_VID_TABLE_ADDR, di->si->memory[mt_local].virtual_addr_start +
		di->dma_desc_offset );
		
	res = acquire_sem_etc( di->dma_sem, 1, B_RELATIVE_TIMEOUT, 1000000 );
	
	// be sure that transmission is really finished
	while( (INREG( di->regs, RADEON_DMA_VID_STATUS ) & RADEON_DMA_STATUS_ACTIVE) != 0 ) {
		SHOW_FLOW0( 0, "DMA transmission still active" );
		snooze( 1000 );
	}
		
	Radeon_FinishDMA( di, src, target, size, lock_mem, contiguous );
	
	//SHOW_FLOW0( 0, "3" );
	
	return res;
}
Пример #14
0
void
ProducerNode::BufferProducer()
{
	// this thread produces one buffer each two seconds,
	// and shedules it to be handled one second later than produced
	// assuming a realtime timesource

	status_t rv;
	for (;;) {
		rv = acquire_sem_etc(mBufferProducerSem,1,B_RELATIVE_TIMEOUT,DELAY);
		if (rv == B_INTERRUPTED) {
			continue;
		} else if (rv == B_OK) {
			// triggered by AdditionalBufferRequested
			release_sem(mBufferProducerSem);
		} else if (rv != B_TIMED_OUT) {
			// triggered by deleting the semaphore (stop request)
			break;
		}
		if (!mOutputEnabled)
			continue;
			
		BBuffer *buffer;
//		out("ProducerNode: RequestBuffer\n");
		buffer = mBufferGroup->RequestBuffer(2048);
		if (!buffer) {
		}
		buffer->Header()->start_time = TimeSource()->Now() + DELAY / 2;
		out("ProducerNode: SendBuffer, sheduled time = %5.4f\n",buffer->Header()->start_time / 1E6);
		rv = SendBuffer(buffer, mOutput.destination);
		if (rv != B_OK) {
		}
	}
}
Пример #15
0
int32 
BBlockFIFO::BeginPut(void **outData, size_t requestSize, bigtime_t timeout)
{
	if (!outData) { FPRINTF(stderr, "BAD_VALUE: outData == NULL\n"); return B_BAD_VALUE; }
	if (_mFlags & flagEndOfData) { FPRINTF(stderr, "EPERM: end of data\n"); return EPERM; }
ENTER_GET
	if (requestSize > _mBufferSize) {
		requestSize = _mBufferSize;
	}
	ssize_t o = _mPutOff + requestSize;
	if (o > (ssize_t)_mAreaSize) {
		o = _mAreaSize;
	}
	int32 req = o-_mPutOff;
	status_t err = acquire_sem_etc(_mPutSem, req, B_TIMEOUT, timeout);
	if (err < B_OK) {
LEAVE_PUT
		FPRINTF(stderr, "BeginPut: acquire_sem_etc() returns %ld (req is %ld)\n", err, req);
		return err;
	}
	*outData = _mBuffer + _mPutOff;
	if (o == (ssize_t)_mAreaSize)
		_mPendingPut = 0;
	else
		_mPendingPut = o;
	atomic_or(&_mFlags, flagPendingPut);
	return req;
}
Пример #16
0
void
ActivityView::_Refresh()
{
	bigtime_t lastTimeout = system_time() - RefreshInterval();
	BMessenger target(this);

	while (true) {
		status_t status = acquire_sem_etc(fRefreshSem, 1, B_ABSOLUTE_TIMEOUT,
			lastTimeout + RefreshInterval());
		if (status == B_OK || status == B_BAD_SEM_ID)
			break;
		if (status == B_INTERRUPTED)
			continue;

		SystemInfo info(fSystemInfoHandler);
		lastTimeout += RefreshInterval();

		fSourcesLock.Lock();

		for (uint32 i = fSources.CountItems(); i-- > 0;) {
			DataSource* source = fSources.ItemAt(i);
			DataHistory* values = fValues.ItemAt(i);

			int64 value = source->NextValue(info);
			values->AddValue(info.Time(), value);
		}

		fSourcesLock.Unlock();

		target.SendMessage(B_INVALIDATE);
	}
}
Пример #17
0
static status_t
ethernet_link_checker(void *)
{
	while (true) {
		status_t status = acquire_sem_etc(sLinkChangeSemaphore, 1,
			B_RELATIVE_TIMEOUT, kLinkCheckInterval);
		if (status == B_BAD_SEM_ID)
			break;

		MutexLocker _(sListLock);

		if (sCheckList.IsEmpty())
			break;

		// check link state of all existing devices

		DoublyLinkedList<ethernet_device>::Iterator iterator
			= sCheckList.GetIterator();
		while (iterator.HasNext()) {
			update_link_state(iterator.Next());
		}
	}

	return B_OK;
}
Пример #18
0
/*!	The BigBrother thread send ping messages to the BMediaRoster of
	all currently running teams. If the reply times out or is wrong,
	the team cleanup function _TeamDied() will be called.
*/
void
AppManager::_BigBrother()
{
	status_t status = B_TIMED_OUT;
	BMessage ping('PING');
	BMessage reply;

	do {
		if (!Lock())
			break;

		bool startOver = false;
		AppMap::iterator iterator = fMap.begin();
		for (; iterator != fMap.end(); iterator++) {
			reply.what = 0;
			status = iterator->second.SendMessage(&ping, &reply, 5000000,
				2000000);
			if (status != B_OK || reply.what != 'PONG') {
				team_id team = iterator->first;
				Unlock();

				_TeamDied(team);
				startOver = true;
				break;
			}
		}

		if (startOver)
			continue;

		Unlock();
		status = acquire_sem_etc(fQuit, 1, B_RELATIVE_TIMEOUT, 2000000);
	} while (status == B_TIMED_OUT || status == B_INTERRUPTED);
}
Пример #19
0
status_t
DavicomDevice::Write(const uint8 *buffer, size_t *numBytes)
{
	size_t numBytesToWrite = *numBytes;
	*numBytes = 0;
	
	if (fRemoved) {
		TRACE_ALWAYS("Error of writing %d bytes to removed device.\n", 
			numBytesToWrite);
		return B_ERROR;
	}

	if (!fHasConnection) {
		TRACE_ALWAYS("Error of writing %d bytes to device while down.\n",
			numBytesToWrite);
		return B_ERROR;
	}

	if (fTXBufferFull) {
		TRACE_ALWAYS("Error of writing %d bytes to device while TX buffer full.\n",
			numBytesToWrite);
		return B_ERROR;
	}

	TRACE_FLOW("Write %d bytes.\n", numBytesToWrite);
	
	uint8 header[kTXHeaderSize];
	header[0] = *numBytes & 0xFF;
	header[1] = *numBytes >> 8;

	iovec txData[] = {
		{ &header, kTXHeaderSize },
		{ (uint8*)buffer, numBytesToWrite }
	};
	
	status_t result = gUSBModule->queue_bulk_v(fWriteEndpoint, 
		txData, 2, _WriteCallback, this);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of queue_bulk_v request:%#010x\n", result);
		return result;
	}

	result = acquire_sem_etc(fNotifyWriteSem, 1, B_CAN_INTERRUPT, 0);
	
	if (result < B_OK) {
		TRACE_ALWAYS("Error of acquiring notify semaphore:%#010x.\n", result);
		return result;
	}

	if (fStatusWrite != B_OK && fStatusWrite != B_CANCELED && !fRemoved) {
		TRACE_ALWAYS("Device status error:%#010x\n", fStatusWrite);
		return fStatusWrite;
	}

	*numBytes = fActualLengthWrite - kTXHeaderSize;;

	TRACE_FLOW("Written %d bytes.\n", *numBytes);
	return B_OK;
}
Пример #20
0
static status_t
b57_read(void *cookie,off_t pos,void *data,size_t *numBytes)
{
	struct be_b57_dev *pUmDevice = (struct be_b57_dev *)cookie;
	PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
	PLM_PACKET pPacket;
	struct B_UM_PACKET *pUmPacket;
	cpu_status cpu;

	if (pUmDevice->block)
		acquire_sem(pUmDevice->packet_release_sem);
	else {
		/* Decrement the receive sem anyway, but don't block
		   this is a horrible hack, but it works. */
		acquire_sem_etc(pUmDevice->packet_release_sem, 1, B_RELATIVE_TIMEOUT, 0);
	}

	cpu = disable_interrupts();
	acquire_spinlock(&pUmDevice->lock);

	pPacket = (PLM_PACKET)
		QQ_PopHead(&pUmDevice->RxPacketReadQ.Container);

	release_spinlock(&pUmDevice->lock);
	restore_interrupts(cpu);

	if (pPacket == 0) {
		*numBytes = -1;
		return B_ERROR;
	}

	pUmPacket = (struct B_UM_PACKET *) pPacket;
	if (pPacket->PacketStatus != LM_STATUS_SUCCESS
		|| pPacket->PacketSize > 1518) {
		cpu = disable_interrupts();
		acquire_spinlock(&pUmDevice->lock);

		QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);

		release_spinlock(&pUmDevice->lock);
		restore_interrupts(cpu);
		*numBytes = -1;
		return B_ERROR;
	}

	if ((pPacket->PacketSize) < *numBytes)
		*numBytes = pPacket->PacketSize;

	memcpy(data,pUmPacket->data,*numBytes);
	cpu = disable_interrupts();
	acquire_spinlock(&pUmDevice->lock);

	QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);

	release_spinlock(&pUmDevice->lock);
	restore_interrupts(cpu);

	return B_OK;
}
Пример #21
0
    PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout)
{
    status_t err;
    if( timeout == PR_INTERVAL_NO_WAIT ) 
    {
        PR_Unlock( cvar->lock );
        PR_Lock( cvar->lock );
        return PR_SUCCESS;
    }

    if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount ) > 1 )
    {
        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
        {
            _MD_ATOMIC_DECREMENT( &cvar->signalBenCount );
            return PR_FAILURE;
        }
    }
    cvar->nw += 1;
    if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 )
    {
        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
    }

    PR_Unlock( cvar->lock );
    if( timeout==PR_INTERVAL_NO_TIMEOUT ) 
    {
    	err = acquire_sem(cvar->sem);
    } 
    else 
    {
    	err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) );
    }

    if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount ) > 1 )
    {
        while (acquire_sem(cvar->signalSem) == B_INTERRUPTED);
    }

    if (cvar->ns > 0)
    {
        release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE);
        cvar->ns -= 1;
    }
    cvar->nw -= 1;
    if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 )
    {
        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
    }

    PR_Lock( cvar->lock );
    if(err==B_NO_ERROR  || (err == B_TIMED_OUT && timeout!=PR_INTERVAL_NO_TIMEOUT))
    {
    return PR_SUCCESS;
}
    return PR_FAILURE;
}
Пример #22
0
	void condition_variable::wait_for(mutex::scoped_lock& l, time_duration rel_time)
	{
		TORRENT_ASSERT(l.locked());
		++m_num_waiters;
		l.unlock();
		acquire_sem_etc(m_sem, 1, B_RELATIVE_TIMEOUT, total_microseconds(rel_time));
		l.lock();
		--m_num_waiters;
	}
Пример #23
0
status_t
ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data)
{
	int cpu_status;

	multi_buffer_info buffer_info;

#ifdef __HAIKU__
	if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK)
		return B_BAD_ADDRESS;
#else
	memcpy(&buffer_info, data, sizeof(buffer_info));
#endif

	buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;

	if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT
		| B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) {
		TRACE("buffer_exchange timeout\n");
	};

	cpu_status = lock();

	// Playback buffers info
	buffer_info.played_real_time = card->played_time;
	buffer_info.played_frames_count = card->frames_count;
	buffer_info.playback_buffer_cycle = (card->buffer - 1)
		% SWAPPING_BUFFERS; //Buffer played

	// Record buffers info
	buffer_info.recorded_real_time = card->played_time;
	buffer_info.recorded_frames_count = card->frames_count;
	buffer_info.record_buffer_cycle = (card->buffer - 1)
		% SWAPPING_BUFFERS; //Buffer filled

	unlock(cpu_status);

/*	if ((card->buffer % 1500) == 0) {
		uint8 reg8, reg8_dir;
		reg8 = read_gpio(card);
		reg8_dir = read_cci_uint8(card, CCI_GPIO_DIRECTION_CONTROL);
		TRACE("DEBUG === GPIO = %d (dir %d)\n", reg8, reg8_dir);

		reg8 = spdif_read(card, CS84xx_VERSION_AND_CHIP_ID);
		TRACE("DEBUG === S/PDif Version : 0x%x\n", reg8);
	}*/

#ifdef __HAIKU__
	if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
		return B_BAD_ADDRESS;
#else
	memcpy(data, &buffer_info, sizeof(buffer_info));
#endif

	return B_OK;
}
Пример #24
0
status_t
ASIXDevice::Write(const uint8 *buffer, size_t *numBytes)
{
	size_t numBytesToWrite = *numBytes;
	*numBytes = 0;

	if (fRemoved) {
		TRACE_ALWAYS("Error of writing %d bytes to removed device.\n",
														numBytesToWrite);
		return B_DEVICE_NOT_FOUND;
	}

	TRACE_FLOW("Write %d bytes.\n", numBytesToWrite);

	TRXHeader header(numBytesToWrite);
	iovec txData[] = {
		{ &header, sizeof(TRXHeader) },
		{ (uint8*)buffer, numBytesToWrite }
	};

	size_t startIndex = fUseTRXHeader ? 0 : 1 ;
	size_t chunkCount = fUseTRXHeader ? 2 : 1 ;

	status_t result = gUSBModule->queue_bulk_v(fWriteEndpoint,
						&txData[startIndex], chunkCount, _WriteCallback, this);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of queue_bulk_v request:%#010x\n", result);
		return result;
	}

	result = acquire_sem_etc(fNotifyWriteSem, 1, B_CAN_INTERRUPT, 0);

	if (result < B_OK) {
		TRACE_ALWAYS("Error of acquiring notify semaphore:%#010x.\n", result);
		return result;
	}

	if (fStatusWrite != B_OK && fStatusWrite != B_CANCELED && !fRemoved) {
		TRACE_ALWAYS("Device status error:%#010x\n", fStatusWrite);
		result = gUSBModule->clear_feature(fWriteEndpoint,
			USB_FEATURE_ENDPOINT_HALT);
		if (result != B_OK) {
			TRACE_ALWAYS("Error during clearing of HALT state:%#010x\n", result);
			return result;
		}
	}

	if (fUseTRXHeader) {
		*numBytes = fActualLengthWrite - sizeof(TRXHeader);
	} else {
		*numBytes = fActualLengthWrite;
	}

	TRACE_FLOW("Written %d bytes.\n", *numBytes);
	return B_OK;
}
Пример #25
0
// _AcquireBenaphore
status_t
RWLocker::_AcquireBenaphore(Benaphore& benaphore, bigtime_t timeout)
{
	status_t error = B_OK;
	if (atomic_add(&benaphore.counter, 1) > 0) {
		error = acquire_sem_etc(benaphore.semaphore, 1, B_ABSOLUTE_TIMEOUT,
								timeout);
	}
	return error;
}
Пример #26
0
void
Filter::Wait()
{
	if (fStarted) {
		// wait for threads to exit
		while (acquire_sem_etc(fWaitForThreads, fN, 0, 0) == B_INTERRUPTED);
		// ready to start again
		fStarted = false;
	}
}
Пример #27
0
void GlutBlocker::WaitEvent(bigtime_t usecs) {
	acquire_sem(gSem);
	if(!events) {			// wait for new event
		sleeping = true;
		release_sem(gSem);
		acquire_sem_etc(eSem, 1, B_TIMEOUT, usecs);	// wait for next event or timeout
	} else {
		release_sem(gSem);
	}
}
Пример #28
0
status_t
SerialDevice::_WriteToDevice()
{
	char *buffer = fOutputBuffer;
	size_t bytesLeft = fOutputBufferSize;
	status_t status = gTTYModule->tty_read(fDeviceTTYCookie, buffer,
		&bytesLeft);
	if (status != B_OK) {
		TRACE_ALWAYS("write to device: failed to read from TTY: %s\n",
			strerror(status));
		return status;
	}

	while (!fDeviceRemoved && bytesLeft > 0) {
		size_t length = MIN(bytesLeft, fWriteBufferSize);
		size_t packetLength = length;
		OnWrite(buffer, &length, &packetLength);

		status = gUSBModule->queue_bulk(fWritePipe, fWriteBuffer, packetLength,
			_WriteCallbackFunction, this);
		if (status != B_OK) {
			TRACE_ALWAYS("write to device: queueing failed with status "
				"0x%08x\n", status);
			return status;
		}

		status = acquire_sem_etc(fDoneWrite, 1, B_CAN_INTERRUPT, 0);
		if (status != B_OK) {
			TRACE_ALWAYS("write to device: failed to get write done sem "
				"0x%08x\n", status);
			return status;
		}

		if (fStatusWrite != B_OK) {
			TRACE("write to device: device status error 0x%08x\n",
				fStatusWrite);
			if (fStatusWrite == B_DEV_STALLED) {
				status = gUSBModule->clear_feature(fWritePipe,
					USB_FEATURE_ENDPOINT_HALT);
				if (status != B_OK) {
					TRACE_ALWAYS("write to device: failed to clear device "
						"halt\n");
					return B_ERROR;
				}
			}

			continue;
		}

		buffer += length;
		bytesLeft -= length;
	}

	return B_OK;
}
Пример #29
0
int32
SerialDevice::DeviceThread(void *data)
{
	SerialDevice *device = (SerialDevice *)data;

	while (!device->fStopDeviceThread) {
		status_t status = gUSBModule->queue_bulk(device->fReadPipe,
			device->fReadBuffer, device->fReadBufferSize,
			device->ReadCallbackFunction, data);
		if (status < B_OK) {
			TRACE_ALWAYS("device thread: queueing failed with error: 0x%08x\n", status);
			break;
		}

		status = acquire_sem_etc(device->fDoneRead, 1, B_CAN_INTERRUPT, 0);
		if (status < B_OK) {
			TRACE_ALWAYS("device thread: failed to get read done sem 0x%08x\n", status);
			break;
		}

		if (device->fStatusRead != B_OK) {
			TRACE("device thread: device status error 0x%08x\n",
				device->fStatusRead);
			if (gUSBModule->clear_feature(device->fReadPipe,
				USB_FEATURE_ENDPOINT_HALT) != B_OK) {
				TRACE_ALWAYS("device thread: failed to clear halt feature\n");
				break;
			}
		}

		char *buffer = device->fReadBuffer;
		size_t readLength = device->fActualLengthRead;
		device->OnRead(&buffer, &readLength);
		if (readLength == 0)
			continue;

		ddrover *ddr = gTTYModule->ddrstart(NULL);
		if (!ddr) {
			TRACE_ALWAYS("device thread: ddrstart problem\n");
			return B_NO_MEMORY;
		}

		while (device->fInputStopped)
			snooze(100);

		gTTYModule->ttyilock(&device->fTTY, ddr, true);
		for (size_t i = 0; i < readLength; i++)
			gTTYModule->ttyin(&device->fTTY, ddr, buffer[i]);

		gTTYModule->ttyilock(&device->fTTY, ddr, false);
		gTTYModule->ddrdone(ddr);
	}

	return B_OK;
}
Пример #30
0
status_t
SerialDevice::Write(const char *buffer, size_t *numBytes)
{
	size_t bytesLeft = *numBytes;
	*numBytes = 0;

	status_t status = mutex_lock(&fWriteLock);
	if (status != B_OK) {
		TRACE_ALWAYS("write: failed to get write lock\n");
		return status;
	}

	if (fDeviceRemoved) {
		mutex_unlock(&fWriteLock);
		return B_DEV_NOT_READY;
	}

	while (bytesLeft > 0) {
		size_t length = MIN(bytesLeft, fWriteBufferSize);
		size_t packetLength = length;
		OnWrite(buffer, &length, &packetLength);

		status = gUSBModule->queue_bulk(fWritePipe, fWriteBuffer,
			packetLength, WriteCallbackFunction, this);
		if (status < B_OK) {
			TRACE_ALWAYS("write: queueing failed with status 0x%08x\n", status);
			break;
		}

		status = acquire_sem_etc(fDoneWrite, 1, B_CAN_INTERRUPT, 0);
		if (status < B_OK) {
			TRACE_ALWAYS("write: failed to get write done sem 0x%08x\n", status);
			break;
		}

		if (fStatusWrite != B_OK) {
			TRACE("write: device status error 0x%08x\n", fStatusWrite);
			status = gUSBModule->clear_feature(fWritePipe,
				USB_FEATURE_ENDPOINT_HALT);
			if (status < B_OK) {
				TRACE_ALWAYS("write: failed to clear device halt\n");
				status = B_ERROR;
				break;
			}
			continue;
		}

		buffer += length;
		*numBytes += length;
		bytesLeft -= length;
	}

	mutex_unlock(&fWriteLock);
	return status;
}