Example #1
0
static status_t
usb_disk_prepare_partial_buffer(device_lun *lun, off_t position, size_t length,
	void *&partialBuffer, void *&blockBuffer, uint32 &blockPosition,
	uint16 &blockCount)
{
	blockPosition = (uint32)(position / lun->block_size);
	blockCount = (uint16)((uint32)((position + length + lun->block_size - 1)
		/ lun->block_size) - blockPosition);
	size_t blockLength = blockCount * lun->block_size;
	blockBuffer = malloc(blockLength);
	if (blockBuffer == NULL) {
		TRACE_ALWAYS("no memory to allocate partial buffer\n");
		return B_NO_MEMORY;
	}

	status_t result = usb_disk_block_read(lun, blockPosition, blockCount,
		blockBuffer, &blockLength);
	if (result != B_OK) {
		TRACE_ALWAYS("block read failed when filling partial buffer\n");
		free(blockBuffer);
		return result;
	}

	off_t offset = position - (blockPosition * lun->block_size);
	partialBuffer = (uint8 *)blockBuffer + offset;
	return B_OK;
}
Example #2
0
DavicomDevice *
lookup_and_create_device(usb_device device)
{
	const usb_device_descriptor *deviceDescriptor
		= gUSBModule->get_device_descriptor(device);

	if (deviceDescriptor == NULL) {
		TRACE_ALWAYS("Error of getting USB device descriptor.\n");
		return NULL;
	}

	TRACE("trying %#06x:%#06x.\n",
			deviceDescriptor->vendor_id, deviceDescriptor->product_id);

	// use binary search to lookup device in table
	uint32 id = deviceDescriptor->vendor_id << 16
					| deviceDescriptor->product_id;
	int left  = -1;
	int right = B_COUNT_OF(gSupportedDevices);
	while ((right - left) > 1) {
		int i = (left + right) / 2;
		((gSupportedDevices[i].Key() < id) ? left : right) = i;
	}

	if (gSupportedDevices[right].Key() == id)
		return new DavicomDevice(device, gSupportedDevices[right]);

	TRACE_ALWAYS("Search for %#x failed %d-%d.\n", id, left, right);
	return NULL;
}
Example #3
0
status_t
AX88772Device::StartDevice()
{
	size_t actualLength = 0;
	status_t result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_IPGS, 0, 0, sizeof(fIPG), fIPG, &actualLength);

	if(result != B_OK) {
		TRACE_ALWAYS("Error of writing IPGs:%#010x\n", result);
		return result;
	}

	if(actualLength != sizeof(fIPG)) {
		TRACE_ALWAYS("Mismatch of written IPGs data. "
				"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
	}

	uint16 rxcontrol = RXCTL_START | RXCTL_MULTICAST | RXCTL_BROADCAST;
	result = WriteRXControlRegister(rxcontrol);
	if(result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
	}

	TRACE_RET(result);
	return result;
}
Example #4
0
status_t
my_modeswitch(my_device* device)
{
	status_t err = B_OK;
	if (device->type[0] == MSG_NONE)
			return B_OK;
	for (int i = 0; i < 3; i++) {
		if (device->type[i] == MSG_NONE)
			break;

		err = my_transfer_data(device, false, kDevicesMsg[device->type[i]],
			sizeof(kDevicesMsg[device->type[i]]));
		if (err != B_OK) {
			TRACE_ALWAYS("send message %d failed\n", i + 1);
			return err;
		}

		TRACE("device switched: %p\n", device);

		char data[36];
		err = my_transfer_data(device, true, data, sizeof(data));
		if (err != B_OK) {
			TRACE_ALWAYS("receive response %d failed 0x%" B_PRIx32 "\n",
				i + 1, device->status);
			return err;
		}
		TRACE("device switched (response length %ld)\n", device->actual_length);
	}

	TRACE("device switched: %p\n", device);

	return B_OK;
}
Example #5
0
status_t
ASIXDevice::SetPromiscuousMode(bool on)
{
	uint16 rxcontrol = 0;

	status_t result = ReadRXControlRegister(&rxcontrol);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of reading RX Control:%#010x\n", result);
		return result;
	}

	if (on)
		rxcontrol |= RXCTL_PROMISCUOUS;
	else
		rxcontrol &= ~RXCTL_PROMISCUOUS;

	result = WriteRXControlRegister(rxcontrol);

	if (result != B_OK ) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
				rxcontrol, result);
	}

	TRACE_RET(result);
	return result;
}
status_t
AX88772Device::_SetupAX88772B()
{
	// Reload EEPROM
	size_t actualLength = 0;
	status_t result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_GPIOS, GPIO_RSE, 0, 0, 0, &actualLength);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of reloading EEPROM: %#010x\n", result);
		return result;
	}

	result = _WakeupPHY();
	if (result != B_OK)
		return result;

	result = WriteRXControlRegister(0);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result);
		return result;
	}

	fIPG[0] = 0x15;
	fIPG[1] = 0x16;
	fIPG[2] = 0x1A;

	return B_OK;
}
void
HIDReport::PrintToStream()
{
	TRACE_ALWAYS("HIDReport %p\n", this);

	const char *typeName = "unknown";
	switch (fType) {
		case HID_REPORT_TYPE_INPUT:
			typeName = "input";
			break;
		case HID_REPORT_TYPE_OUTPUT:
			typeName = "output";
			break;
		case HID_REPORT_TYPE_FEATURE:
			typeName = "feature";
			break;
	}

	TRACE_ALWAYS("\ttype: %u %s\n", fType, typeName);
	TRACE_ALWAYS("\treport id: %u\n", fReportID);
	TRACE_ALWAYS("\treport size: %" B_PRIu32 " bits = %" B_PRIu32 " bytes\n",
		fReportSize, (fReportSize + 7) / 8);

	TRACE_ALWAYS("\titem count: %" B_PRIu32 "\n", fItemsUsed);
	for (uint32 i = 0; i < fItemsUsed; i++) {
		HIDReportItem *item = fItems[i];
		if (item != NULL)
			item->PrintToStream(1);
	}
}
status_t
init_driver()
{
    status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCIModule);
    if (status < B_OK) {
        return ENOSYS;
    }

    load_settings();

    TRACE_ALWAYS("%s\n", kVersion);

    pci_info info = {0};
    for (long i = 0; B_OK == (*gPCIModule->get_nth_pci_info)(i, &info); i++) {
        for (size_t idx = 0; idx < _countof(cardInfos); idx++) {
            if (info.vendor_id == cardInfos[idx].VendorId()
                    && info.device_id == cardInfos[idx].DeviceId())
            {
                TRACE_ALWAYS("Found:%s %#010x\n",
                             cardInfos[idx].Description(), cardInfos[idx].Id());

                if (numCards == MAX_DEVICES) {
                    break;
                }

                Device* device = new Device(cardInfos[idx], info);
                if (device == 0) {
                    return ENODEV;
                }

                status_t status = device->InitCheck();
                if (status < B_OK) {
                    delete device;
                    break;
                }

                status = device->SetupDevice();
                if (status < B_OK) {
                    delete device;
                    break;
                }

                char name[DEVNAME_LEN] = {0};
                sprintf(name, "net/%s/%ld", cardInfos[idx].Name(), numCards);
                gDeviceNames[numCards] = strdup(name);
                gDevices[numCards++] = device;
            }
        }
    }

    if (numCards == 0) {
        put_module(B_PCI_MODULE_NAME);
        return ENODEV;
    }

    add_debugger_command(DRIVER_NAME, SiS19X_DebuggerCommand,
                         "SiS190/191 Ethernet driver info");

    return B_OK;
}
Example #9
0
void
ASIXDevice::_NotifyCallback(void *cookie, int32 status, void *data,
	uint32 actualLength)
{
	ASIXDevice *device = (ASIXDevice *)cookie;
	atomic_add(&device->fInsideNotify, 1);
	if (status == B_CANCELED || device->fRemoved) {
		atomic_add(&device->fInsideNotify, -1);
		return;
	}

	if (status != B_OK) {
		TRACE_ALWAYS("Device status error:%#010x\n", status);
		status_t result = gUSBModule->clear_feature(device->fNotifyEndpoint,
													USB_FEATURE_ENDPOINT_HALT);
		if (result != B_OK)
			TRACE_ALWAYS("Error during clearing of HALT state:%#010x.\n",
				result);
	}

	// parse data in overriden class
	device->OnNotify(actualLength);

	// schedule next notification buffer
	gUSBModule->queue_interrupt(device->fNotifyEndpoint, device->fNotifyBuffer,
		device->fNotifyBufferLength, _NotifyCallback, device);
	atomic_add(&device->fInsideNotify, -1);
}
Example #10
0
status_t
usb_disk_inquiry(device_lun *lun)
{
	uint32 dataLength = sizeof(scsi_inquiry_6_parameter);
	scsi_inquiry_6_parameter parameter;
	status_t result = B_ERROR;
	for (uint32 tries = 0; tries < 3; tries++) {
		result = usb_disk_operation(lun, SCSI_INQUIRY_6, 6, 0, dataLength,
			&parameter, &dataLength, true);
		if (result == B_OK)
			break;
	}
	if (result != B_OK) {
		TRACE_ALWAYS("getting inquiry data failed\n");
		lun->device_type = B_DISK;
		lun->removable = true;
		return result;
	}

	TRACE("peripherial_device_type  0x%02x\n", parameter.peripherial_device_type);
	TRACE("peripherial_qualifier    0x%02x\n", parameter.peripherial_qualifier);
	TRACE("removable_medium         %s\n", parameter.removable_medium ? "yes" : "no");
	TRACE("version                  0x%02x\n", parameter.version);
	TRACE("response_data_format     0x%02x\n", parameter.response_data_format);	
	TRACE_ALWAYS("vendor_identification    \"%.8s\"\n", parameter.vendor_identification);	
	TRACE_ALWAYS("product_identification   \"%.16s\"\n", parameter.product_identification);	
	TRACE_ALWAYS("product_revision_level   \"%.4s\"\n", parameter.product_revision_level);	
	lun->device_type = parameter.peripherial_device_type; /* 1:1 mapping */
	lun->removable = (parameter.removable_medium == 1);
	return B_OK;
}
Example #11
0
File: FTDI.cpp Project: DonCN/haiku
status_t
FTDIDevice::SetControlLineState(uint16 state)
{
	TRACE_FUNCALLS("> FTDIDevice::SetControlLineState(0x%08x, 0x%04x)\n", this, state);

	int32 control;
	control = (state & USB_CDC_CONTROL_SIGNAL_STATE_RTS) ? FTDI_SIO_SET_RTS_HIGH
		: FTDI_SIO_SET_RTS_LOW;

	size_t length = 0;
	status_t status = gUSBModule->send_request(Device(),
		USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
		FTDI_SIO_MODEM_CTRL, control,
		FTDI_PIT_DEFAULT, 0, NULL, &length);

	if (status != B_OK)
		TRACE_ALWAYS("= FTDIDevice::SetControlLineState(): control set request failed: 0x%08x\n", status);

	control = (state & USB_CDC_CONTROL_SIGNAL_STATE_DTR) ? FTDI_SIO_SET_DTR_HIGH
		: FTDI_SIO_SET_DTR_LOW;

	status = gUSBModule->send_request(Device(),
		USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
		FTDI_SIO_MODEM_CTRL, control,
		FTDI_PIT_DEFAULT, 0, NULL, &length);

	if (status != B_OK)
		TRACE_ALWAYS("= FTDIDevice::SetControlLineState(): control set request failed: 0x%08x\n", status);

	TRACE_FUNCRET("< FTDIDevice::SetControlLineState() returns: 0x%08x\n", status);
	return status;
}
Example #12
0
status_t
usb_disk_mode_sense(device_lun *lun)
{
	uint32 dataLength = sizeof(scsi_mode_sense_6_parameter);

	uint8 commandBlock[12];
	memset(commandBlock, 0, sizeof(commandBlock));

	commandBlock[0] = SCSI_MODE_SENSE_6;
	commandBlock[1] = lun->logical_unit_number << 5;
	commandBlock[2] = 0; // Current values
	commandBlock[7] = dataLength >> 8;
	commandBlock[8] = dataLength;

	scsi_mode_sense_6_parameter parameter;
	status_t result = usb_disk_operation(lun, commandBlock,
		&parameter, &dataLength, true);
	if (result != B_OK) {
		TRACE_ALWAYS("getting mode sense data failed\n");
		return result;
	}

	lun->write_protected
		= (parameter.device_specific & SCSI_DEVICE_SPECIFIC_WRITE_PROTECT) != 0;
	TRACE_ALWAYS("write protected: %s\n", lun->write_protected ? "yes" : "no");
	return B_OK;
}
Example #13
0
HIDReport *
HIDParser::_FindOrCreateReport(uint8 type, uint8 id)
{
	HIDReport *report = FindReport(type, id);
	if (report != NULL)
		return report;

	report = new(std::nothrow) HIDReport(this, type, id);
	if (report == NULL) {
		TRACE_ALWAYS("no memory when allocating report\n");
		return NULL;
	}

	HIDReport **newReports = (HIDReport **)realloc(fReports,
		(fReportCount + 1) * sizeof(HIDReport *));
	if (newReports == NULL) {
		TRACE_ALWAYS("no memory when growing report list\n");
		delete report;
		return NULL;
	}

	fReports = newReports;
	fReports[fReportCount++] = report;
	return report;
}
Example #14
0
/* init_driver - optional function - called every time the driver is loaded. */
status_t init_driver (void){
  int i;
  status_t status = B_OK;
  load_setting();
  create_log();

  TRACE_FUNCALLS("init_driver\n");
  
  if((status = get_module(B_USB_MODULE_NAME, (module_info **)&usb)) == B_OK){
    if(usb){
      for(i = 0; i < DEVICES_COUNT; i++)
        usb_vision_devices[i] = 0;
        
      usb_vision_names[0] = NULL;  

      (*usb->register_driver)(DRIVER_NAME, supported_devices, SIZEOF(supported_devices), DRIVER_NAME);
      (*usb->install_notify)(DRIVER_NAME, &notify_hooks);

      usb_vision_lock = create_sem(1, DRIVER_NAME"_devices_table_lock");
    }else{
      status = B_ERROR;
      TRACE_ALWAYS("init_driver failed: usb:%08x", usb);
    } 
  }else
    TRACE_ALWAYS("init_driver failed:%lx cannot get a module %s", status, B_USB_MODULE_NAME);
  
  TRACE_FUNCRET("init_driver returns:%08x\n", status);
  return status;
}
Example #15
0
status_t
BeceemCPU::CPURun()
{
	uint32 clockRegister = 0;

	// Read current clock register contents
	if (BizarroReadRegister(CLOCK_RESET_CNTRL_REG_1,
		sizeof(clockRegister), &clockRegister) != B_OK) {
		TRACE_ALWAYS("Error: Read of clock reset reg failure\n");
		return B_ERROR;
	}

	// Adjust clock register contents to start cpu
	if (fWmxDevice->CPUFlashBoot)
		clockRegister &= ~(1 << 30);
	else
		clockRegister |= (1 << 30);

	// Write new clock register contents
	if (BizarroWriteRegister(CLOCK_RESET_CNTRL_REG_1,
		sizeof(clockRegister), &clockRegister) != B_OK) {
		TRACE_ALWAYS("Error: Write of clock reset reg failure\n");
		return B_ERROR;
	}

	return B_OK;
}
Example #16
0
status_t
DavicomDevice::SetupDevice(bool deviceReplugged)
{
	ether_address address;
	status_t result = ReadMACAddress(&address);
	if(result != B_OK) {
		TRACE_ALWAYS("Error reading MAC address:%#010x\n", result);
		return result;
	}

	TRACE("MAC address is:%02x:%02x:%02x:%02x:%02x:%02x\n",
				address.ebyte[0], address.ebyte[1], address.ebyte[2], 
				address.ebyte[3], address.ebyte[4], address.ebyte[5]);

	if(deviceReplugged) {
		// this might be the same device that was replugged - read the MAC address
		// (which should be at the same index) to make sure
		if(memcmp(&address, &fMACAddress, sizeof(address)) != 0) {
			TRACE_ALWAYS("Cannot replace device with MAC address:"
												"%02x:%02x:%02x:%02x:%02x:%02x\n",
				fMACAddress.ebyte[0], fMACAddress.ebyte[1], fMACAddress.ebyte[2], 
				fMACAddress.ebyte[3], fMACAddress.ebyte[4], fMACAddress.ebyte[5]);
			return B_BAD_VALUE; // is not the same
		}
	} else 
		fMACAddress = address;
	
	return B_OK; 
}
Example #17
0
status_t
DavicomDevice::SetPromiscuousMode(bool on)
{

	/* load multicast filter and update promiscious mode bit */
	uint8_t rxmode;

	status_t result = _ReadRegister(RCR, 1, &rxmode);
	if (result != B_OK) {
		TRACE_ALWAYS("Error reading RX Control:%#010x\n", result);
		return result;
	}
	rxmode &= ~(RCR_ALL | RCR_PRMSC);

	if (on)
		rxmode |= RCR_ALL | RCR_PRMSC;
/*	else if (ifp->if_flags & IFF_ALLMULTI)
		rxmode |= RCR_ALL; */

	/* write new mode bits */
	result = _Write1Register(RCR, rxmode);
	if(result != B_OK) {
		TRACE_ALWAYS("Error writing %#04x to RX Control:%#010x\n", rxmode, result);
	} 

	return result;
}
Example #18
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;
}
Example #19
0
status_t
usb_printer_transfer_data(printer_device *device, bool directionIn, void *data,
	size_t dataLength)
{
	status_t result = gUSBModule->queue_bulk(directionIn ? device->bulk_in
		: device->bulk_out, data, dataLength, usb_printer_callback, device);
	if (result != B_OK) {
		TRACE_ALWAYS("failed to queue data transfer\n");
		return result;
	}

	do {
		bigtime_t timeout = directionIn ? READ_TIMEOUT : WRITE_TIMEOUT;
		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;
}
Example #20
0
status_t
AX88178Device::SetupDevice(bool deviceReplugged)
{
	status_t result = ASIXDevice::SetupDevice(deviceReplugged);
	if (result != B_OK) {
		return result;
	}

	result = fMII.Init(fDevice);

	if (result != B_OK) {
		return result;
	}

	size_t actualLength = 0;
	// get the "magic" word from EEPROM
	result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_SROM_ENABLE, 0, 0, 0, 0, &actualLength);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of enabling SROM access:%#010x\n", result);
		return result;
	}

	uint16 eepromData = 0;
	status_t op_result = gUSBModule->send_request(fDevice,
							USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
							READ_SROM, 0x17, 0,
							sizeof(eepromData), &eepromData, &actualLength);

	if (op_result != B_OK) {
		TRACE_ALWAYS("Error of reading SROM data:%#010x\n", result);
	}

	if (actualLength != sizeof(eepromData)) {
		TRACE_ALWAYS("Mismatch of reading SROM data."
						"Read %d bytes instead of %d\n",
						actualLength, sizeof(eepromData));
	}

	result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_SROM_DISABLE, 0, 0, 0, 0, &actualLength);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of disabling SROM access: %#010x\n", result);
		return result;
	}

	if (op_result != B_OK) {
		return op_result;
	}

	// some shaman's dances with GPIO
	struct GPIOData {
		bigtime_t	delay;
		uint16 		value;
	} GPIOCommands[] = {
Example #21
0
status_t
usb_serial_device_added(usb_device device, void **cookie)
{
	TRACE_FUNCALLS("> usb_serial_device_added(0x%08x, 0x%08x)\n", device, cookie);

	status_t status = B_OK;
	const usb_device_descriptor *descriptor
		= gUSBModule->get_device_descriptor(device);

	TRACE_ALWAYS("probing device: 0x%04x/0x%04x\n", descriptor->vendor_id,
		descriptor->product_id);

	*cookie = NULL;
	SerialDevice *serialDevice = SerialDevice::MakeDevice(device,
		descriptor->vendor_id, descriptor->product_id);

	const usb_configuration_info *configuration;
	for (int i = 0; i < descriptor->num_configurations; i++) {
		configuration = gUSBModule->get_nth_configuration(device, i);
		if (configuration == NULL)
			continue;

		status = serialDevice->AddDevice(configuration);
		if (status == B_OK) {
			// Found!
			break;
		}
	}

	if (status < B_OK) {
		delete serialDevice;
		return status;
	}


	acquire_sem(gDriverLock);
	for (int32 i = 0; i < DEVICES_COUNT; i++) {
		if (gSerialDevices[i] != NULL)
			continue;

		status = serialDevice->Init();
		if (status < B_OK) {
			delete serialDevice;
			return status;
		}

		gSerialDevices[i] = serialDevice;
		*cookie = serialDevice;

		release_sem(gDriverLock);
		TRACE_ALWAYS("%s (0x%04x/0x%04x) added\n", serialDevice->Description(),
			descriptor->vendor_id, descriptor->product_id);
		return B_OK;
	}

	release_sem(gDriverLock);
	return B_ERROR;
}
Example #22
0
Device::Device(usb_device device)
			:
			fStatus(B_ERROR),
			fOpen(false),
			fRemoved(false),
			fInsideNotify(0),
			fDevice(device),
			fNonBlocking(false),
			fAudioControl(this),
			fControlEndpoint(0),
			fInStreamEndpoint(0),
			fOutStreamEndpoint(0),
			fNotifyReadSem(-1),
			fNotifyWriteSem(-1),
			fNotifyBuffer(NULL),
			fNotifyBufferLength(0),
			fBuffersReadySem(-1)
{
	const usb_device_descriptor* deviceDescriptor
		= gUSBModule->get_device_descriptor(device);

	if (deviceDescriptor == NULL) {
		TRACE_ALWAYS("Error of getting USB device descriptor.\n");
		return;
	}

	fVendorID = deviceDescriptor->vendor_id;
	fProductID = deviceDescriptor->product_id;

	fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read");
	if (fNotifyReadSem < B_OK) {
		TRACE_ALWAYS("Error of creating read notify semaphore:%#010x\n",
															fNotifyReadSem);
		return;
	}

	fNotifyWriteSem = create_sem(0, DRIVER_NAME"_notify_write");
	if (fNotifyWriteSem < B_OK) {
		TRACE_ALWAYS("Error of creating write notify semaphore:%#010x\n",
															fNotifyWriteSem);
		return;
	}

	fBuffersReadySem = create_sem(0, DRIVER_NAME "_buffers_ready");
	if (fBuffersReadySem < B_OK) {
		TRACE_ALWAYS("Error of creating ready buffers semaphore:%#010x\n",
															fBuffersReadySem);
		return;
	}

	if (_SetupEndpoints() != B_OK) {
		return;
	}

	// must be set in derived class constructor
	fStatus = B_OK;
}
Example #23
0
status_t
usb_disk_inquiry(device_lun *lun)
{
	size_t dataLength = sizeof(scsi_inquiry_6_parameter);

	uint8 commandBlock[12];
	memset(commandBlock, 0, sizeof(commandBlock));

	commandBlock[0] = SCSI_INQUIRY_6;
	commandBlock[1] = lun->logical_unit_number << 5;
	commandBlock[2] = 0; // page code
	commandBlock[4] = dataLength;

	scsi_inquiry_6_parameter parameter;
	status_t result = B_ERROR;
	for (uint32 tries = 0; tries < 3; tries++) {
		result = usb_disk_operation(lun, commandBlock, &parameter, &dataLength,
			true);
		if (result == B_OK)
			break;
	}
	if (result != B_OK) {
		TRACE_ALWAYS("getting inquiry data failed\n");
		lun->device_type = B_DISK;
		lun->removable = true;
		return result;
	}

	TRACE("peripherial_device_type  0x%02x\n",
		parameter.peripherial_device_type);
	TRACE("peripherial_qualifier    0x%02x\n",
		parameter.peripherial_qualifier);
	TRACE("removable_medium         %s\n",
		parameter.removable_medium ? "yes" : "no");
	TRACE("version                  0x%02x\n", parameter.version);
	TRACE("response_data_format     0x%02x\n", parameter.response_data_format);
	TRACE_ALWAYS("vendor_identification    \"%.8s\"\n",
		parameter.vendor_identification);
	TRACE_ALWAYS("product_identification   \"%.16s\"\n",
		parameter.product_identification);
	TRACE_ALWAYS("product_revision_level   \"%.4s\"\n",
		parameter.product_revision_level);

	memcpy(lun->vendor_name, parameter.vendor_identification,
		MIN(sizeof(lun->vendor_name), sizeof(parameter.vendor_identification)));
	memcpy(lun->product_name, parameter.product_identification,
		MIN(sizeof(lun->product_name),
			sizeof(parameter.product_identification)));
	memcpy(lun->product_revision, parameter.product_revision_level,
		MIN(sizeof(lun->product_revision),
			sizeof(parameter.product_revision_level)));

	lun->device_type = parameter.peripherial_device_type; /* 1:1 mapping */
	lun->removable = (parameter.removable_medium == 1);
	return B_OK;
}
Example #24
0
DavicomDevice::DavicomDevice(usb_device device, const char *description)
	:	fStatus(B_ERROR),
		fOpen(false),
		fRemoved(false),
		fInsideNotify(0),
		fDevice(device),
		fDescription(description), 
		fNonBlocking(false),		
		fNotifyEndpoint(0), 
		fReadEndpoint(0), 
		fWriteEndpoint(0),
		fNotifyReadSem(-1), 
		fNotifyWriteSem(-1), 
		fNotifyBuffer(NULL),
		fLinkStateChangeSem(-1), 
		fHasConnection(false)
{ 
	const usb_device_descriptor
			*deviceDescriptor = gUSBModule->get_device_descriptor(device);

	if (deviceDescriptor == NULL) {
		TRACE_ALWAYS("Error of getting USB device descriptor.\n");
		return;
	}

	fVendorID = deviceDescriptor->vendor_id;
	fProductID = deviceDescriptor->product_id;

	fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read");
	if (fNotifyReadSem < B_OK) {
		TRACE_ALWAYS("Error of creating read notify semaphore:%#010x\n",
															fNotifyReadSem);
		return;
	}

	fNotifyWriteSem = create_sem(0, DRIVER_NAME"_notify_write");
	if (fNotifyWriteSem < B_OK) {
		TRACE_ALWAYS("Error of creating write notify semaphore:%#010x\n", 
															fNotifyWriteSem);
		return;
	}

	fNotifyBuffer = (uint8*)malloc(kNotifyBufferSize);
	if (fNotifyBuffer == NULL) {
		TRACE_ALWAYS("Error allocating notify buffer\n");
		return;
	}

	if (_SetupEndpoints() != B_OK) {
		return;
	}
	
	// TODO : others inits here ?

	fStatus = B_OK;
}
Example #25
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;
}
Example #26
0
status_t
DavicomDevice::StartDevice()
{
	uint8 registerValue = 0;

	/* disable loopback  */
	status_t result = _ReadRegister(NCR, 1, &registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error reading NCR: %#010x.\n", result);
		return result;
	}
	if (registerValue & NCR_EXT_PHY)
		TRACE_ALWAYS("Device uses external PHY\n");
	registerValue &= ~NCR_LBK;
	result = _Write1Register(NCR, registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error writing %#02X to NCR: %#010x.\n", registerValue, result);
		return result;
	}

	/* Initialize RX control register */
	result = _ReadRegister(RCR, 1, &registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error reading RCR: %#010x.\n", result);
		return result;
	}
	registerValue &= RCR_DIS_LONG & RCR_DIS_CRC & RCR_RXEN;
	result = _Write1Register(RCR, registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error writing %#02X to RCR: %#010x.\n", registerValue, result);
		return result;
	}

	/* clear POWER_DOWN state of internal PHY */
	result = _ReadRegister(GPCR, 1, &registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error reading GPCR: %#010x.\n", result);
		return result;
	}
	registerValue &= GPCR_GEP_CNTL0;
	result = _Write1Register(GPCR, registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error writing %#02X to GPCR: %#010x.\n", registerValue, result);
		return result;
	}

	result = _ReadRegister(GPR, 1, &registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error reading GPR: %#010x.\n", result);
		return result;
	}
	registerValue &= ~GPR_GEP_GEPIO0;
	result = _Write1Register(GPR, registerValue);
	if (result != B_OK) {
		TRACE_ALWAYS("Error writing %#02X to GPR: %#010x.\n", registerValue, result);
		return result;
	}

	return B_OK;
}
Example #27
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;
}
Example #28
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;
}
Example #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;
}
Example #30
0
ASIXDevice::ASIXDevice(usb_device device, DeviceInfo& deviceInfo)
		:
		fDevice(device),
		fStatus(B_ERROR),
		fOpen(false),
		fRemoved(false),
		fHasConnection(false),
		fNonBlocking(false),
		fInsideNotify(0),
		fFrameSize(0),
		fNotifyEndpoint(0),
		fReadEndpoint(0),
		fWriteEndpoint(0),
		fActualLengthRead(0),
		fActualLengthWrite(0),
		fStatusRead(B_OK),
		fStatusWrite(B_OK),
		fNotifyReadSem(-1),
		fNotifyWriteSem(-1),
		fNotifyBuffer(NULL),
		fNotifyBufferLength(0),
		fLinkStateChangeSem(-1),
		fUseTRXHeader(false),
		fReadNodeIDRequest(kInvalidRequest)
{
	fDeviceInfo = deviceInfo;

	fIPG[0] = 0x15;
	fIPG[1] = 0x0c;
	fIPG[2] = 0x12;

	memset(&fMACAddress, 0, sizeof(fMACAddress));

	fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read");
	if (fNotifyReadSem < B_OK) {
		TRACE_ALWAYS("Error of creating read notify semaphore:%#010x\n",
															fNotifyReadSem);
		return;
	}

	fNotifyWriteSem = create_sem(0, DRIVER_NAME"_notify_write");
	if (fNotifyWriteSem < B_OK) {
		TRACE_ALWAYS("Error of creating write notify semaphore:%#010x\n",
															fNotifyWriteSem);
		return;
	}

	if (_SetupEndpoints() != B_OK) {
		return;
	}

	// must be set in derived class constructor
	// fStatus = B_OK;
}