static status_t add_device(usb_vision_device *uvd, const usb_configuration_info *uci){ usb_endpoint_info *control_epi = NULL; usb_endpoint_info *data_epi = NULL; status_t status = ENODEV; int i = 0; usb_interface_info *uii = uci->interface[0].active; TRACE_FUNCALLS("> add_device(%08x, %08x)\n", uvd, uci); for(i=0; i < uii->endpoint_count; i++){ if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_ISOCHRONOUS){ if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN) == USB_EP_ADDR_DIR_IN){ data_epi = &uii->endpoint[i]; TRACE("iso_ep:%d\n", i); } } if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_CONTROL){ control_epi = &uii->endpoint[i]; TRACE("cont_ep:%d\n", i); } if(control_epi && data_epi) break; } if(control_epi && data_epi){ status = create_add_device(uvd, uci, control_epi, data_epi); } TRACE_FUNCRET("< create_add_device returns:%08x\n", status); return status; }
/* 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, ¬ify_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; }
/* usb_serial_close - handle close() calls */ static status_t usb_serial_close(void *cookie) { TRACE_FUNCALLS("> usb_serial_close(0x%08x)\n", cookie); SerialDevice *device = (SerialDevice *)cookie; return device->Close(); }
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; }
static status_t usb_vision_open (const char *name, uint32 flags, void** cookie) { int i; status_t status = ENODEV; TRACE_FUNCALLS("usb_vision_open:%s flags:%d cookie:%08x\n", name, flags, cookie); for(i = 0; i < DEVICES_COUNT; i++) TRACE("%08x\n", usb_vision_devices[i]); *cookie = NULL; i = strtol(name + BASENAME_LEN, NULL, 10); if(i >= 0 && i < DEVICES_COUNT){ acquire_sem(usb_vision_lock); if(usb_vision_devices[i]){ if(atomic_add(&usb_vision_devices[i]->open_count, 1) == 0){ *cookie = usb_vision_devices[i]; TRACE("cookie in open:%08x\n", *cookie); status = B_OK; }else{ atomic_add(&usb_vision_devices[i]->open_count, -1); status = B_BUSY; } } release_sem(usb_vision_lock); } TRACE_FUNCRET("usb_vision_open returns:%08x\n", status); return status; }
status_t pc_serial_device_removed(void *cookie) { TRACE_FUNCALLS("> pc_serial_device_removed(0x%08x)\n", cookie); acquire_sem(gDriverLock); SerialDevice *device = (SerialDevice *)cookie; for (int32 i = 0; i < DEVICES_COUNT; i++) { if (gSerialDevices[i] == device) { if (device->IsOpen()) { // the device will be deleted upon being freed device->Removed(); } else { delete device; gSerialDevices[i] = NULL; } break; } } release_sem(gDriverLock); TRACE_FUNCRET("< pc_serial_device_removed() returns\n"); return B_OK; }
/* usb_vision_close - handle close() calls */ static status_t usb_vision_close (void* cookie) { status_t status = B_OK;//ENODEV; TRACE_FUNCALLS("usb_vision_close:%08x\n", cookie); TRACE_FUNCRET("usb_vision_close returns:%08x\n", status); return status; }
/* usb_serial_read - handle read() calls */ static status_t usb_serial_read(void *cookie, off_t position, void *buffer, size_t *numBytes) { TRACE_FUNCALLS("> usb_serial_read(0x%08x, %Ld, 0x%08x, %d)\n", cookie, position, buffer, *numBytes); SerialDevice *device = (SerialDevice *)cookie; return device->Read((char *)buffer, numBytes); }
/* usb_serial_control - handle ioctl calls */ static status_t usb_serial_control(void *cookie, uint32 op, void *arg, size_t length) { TRACE_FUNCALLS("> usb_serial_control(0x%08x, 0x%08x, 0x%08x, %d)\n", cookie, op, arg, length); SerialDevice *device = (SerialDevice *)cookie; return device->Control(op, arg, length); }
/* usb_serial_deselect - handle select exit */ static status_t usb_serial_deselect(void *cookie, uint8 event, selectsync *sync) { TRACE_FUNCALLS("> usb_serial_deselect(0x%08x, 0x%08x, %p)\n", cookie, event, sync); SerialDevice *device = (SerialDevice *)cookie; return device->DeSelect(event, sync); }
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; }
/* usb_serial_close - handle close() calls */ static status_t usb_serial_close(void *cookie) { TRACE_FUNCALLS("> usb_serial_close(0x%08x)\n", cookie); SerialDevice *device = (SerialDevice *)cookie; status_t status = device->Close(); TRACE_FUNCRET("< usb_serial_close() returns: 0x%08x\n", status); return status; }
/* usb_serial_deselect - handle select exit */ static status_t usb_serial_deselect(void *cookie, uint8 event, selectsync *sync) { TRACE_FUNCALLS("> usb_serial_deselect(0x%08x, 0x%08x, %p)\n", cookie, event, sync); SerialDevice *device = (SerialDevice *)cookie; status_t status = device->DeSelect(event, sync); TRACE_FUNCRET("< usb_serial_deselect() returns: 0x%08x\n", status); return status; }
/* usb_serial_control - handle ioctl calls */ static status_t usb_serial_control(void *cookie, uint32 op, void *arg, size_t length) { TRACE_FUNCALLS("> usb_serial_control(0x%08x, 0x%08x, 0x%08x, %d)\n", cookie, op, arg, length); SerialDevice *device = (SerialDevice *)cookie; status_t status = device->Control(op, arg, length); TRACE_FUNCRET("< usb_serial_control() returns: 0x%08x\n", status); return status; }
/* usb_serial_write - handle write() calls */ static status_t usb_serial_write(void *cookie, off_t position, const void *buffer, size_t *numBytes) { TRACE_FUNCALLS("> usb_serial_write(0x%08x, %Ld, 0x%08x, %d)\n", cookie, position, buffer, *numBytes); SerialDevice *device = (SerialDevice *)cookie; status_t status = device->Write((const char *)buffer, numBytes); TRACE_FUNCRET("< usb_serial_write() returns: 0x%08x\n", status); return status; }
void SerialDevice::WriteCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength) { TRACE_FUNCALLS("write callback: cookie: 0x%08x status: 0x%08x data: 0x%08x len: %lu\n", cookie, status, data, actualLength); SerialDevice *device = (SerialDevice *)cookie; device->fActualLengthWrite = actualLength; device->fStatusWrite = status; release_sem_etc(device->fDoneWrite, 1, B_DO_NOT_RESCHEDULE); }
void SerialDevice::_ReadCallbackFunction(void *cookie, status_t status, void *data, uint32 actualLength) { TRACE_FUNCALLS("read callback: cookie: 0x%08x status: 0x%08x data: 0x%08x " "length: %lu\n", cookie, status, data, actualLength); SerialDevice *device = (SerialDevice *)cookie; device->fActualLengthRead = actualLength; device->fStatusRead = status; release_sem_etc(device->fDoneRead, 1, B_DO_NOT_RESCHEDULE); }
status_t ProlificDevice::AddDevice(const usb_configuration_info *config) { TRACE_FUNCALLS("> ProlificDevice::AddDevice(%08x, %08x)\n", this, config); // check for device type. // Linux checks for type 0, 1 and HX, but handles 0 and 1 the same. // We'll just check for HX then. const usb_device_descriptor *deviceDescriptor = NULL; deviceDescriptor = gUSBModule->get_device_descriptor(Device()); if (deviceDescriptor) { fIsHX = (deviceDescriptor->device_class != 0x02 && deviceDescriptor->max_packet_size_0 == 0x40); } int32 pipesSet = 0; status_t status = ENODEV; if (config->interface_count > 0) { usb_interface_info *interface = config->interface[0].active; for (size_t i = 0; i < interface->endpoint_count; i++) { usb_endpoint_info *endpoint = &interface->endpoint[i]; if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_INTERRUPT) { if (endpoint->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) { SetControlPipe(endpoint->handle); pipesSet++; } } } /* They say that USB-RSAQ1 has 2 interfaces */ if (config->interface_count >= 2) interface = config->interface[1].active; for (size_t i = 0; i < interface->endpoint_count; i++) { usb_endpoint_info *endpoint = &interface->endpoint[i]; if (endpoint->descr->attributes == USB_ENDPOINT_ATTR_BULK) { if (endpoint->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) SetReadPipe(endpoint->handle); else SetWritePipe(endpoint->handle); if (++pipesSet >= 3) break; } } if (pipesSet >= 3) status = B_OK; } TRACE_FUNCRET("< ProlificDevice::AddDevice() returns: 0x%08x\n", status); return status; }
/* usb_vision_free - called after the last device is closed, and after all i/o is complete. */ static status_t usb_vision_free (void* cookie) { status_t status = B_OK; TRACE_FUNCALLS("usb_vision_free:%08x\n", cookie); if(cookie){ usb_vision_device *uvd = (usb_vision_device *)cookie; atomic_add(&uvd->open_count, -1); } TRACE_FUNCRET("usb_vision_free returns:%08x\n", status); return status; }
static status_t create_add_device(usb_vision_device *uvd, const struct usb_configuration_info *uci, struct usb_endpoint_info *control_epi, struct usb_endpoint_info *data_epi){ // char name[32]; status_t status = ENODEV; // size_t buf_len; int i = 0; TRACE_FUNCALLS("create_add_device(%08x, %08x, %08x, %08x)\n", uvd, uci, control_epi, data_epi); acquire_sem(usb_vision_lock); for(i = 0; i < DEVICES_COUNT; i++){ if(usb_vision_devices[i] != NULL) continue; usb_vision_devices[i] = uvd; /* usd->active = 1; usd->open = 0; sprintf(name, "usb_vision:%d:done_read", i ); usd->done_read = create_sem(0, name); sprintf(name, "usb_vision:%d:done_write", i); usd->done_write = create_sem(0, name); usd->tty = NULL; buf_len = usd->read_buffer_size + usd->write_buffer_size + usd->interrupt_buffer_size; usd->buffers_area = create_area("usb_serial:buffers_area", (void *)&usd->read_buffer, B_ANY_KERNEL_ADDRESS, ROUNDUP(buf_len, B_PAGE_SIZE), B_CONTIGUOUS, B_READ_AREA|B_WRITE_AREA); usd->write_buffer = usd->read_buffer + usd->read_buffer_size; usd->interrupt_buffer = usd->write_buffer + usd->write_buffer_size; */ (*usb->set_configuration)(uvd->dev, uci); uvd->control_pipe = control_epi->handle; uvd->data_pipe = data_epi->handle; status = B_OK; break; } release_sem(usb_vision_lock); TRACE_FUNCRET("add_device returns:%08x\n", status); return status; }
status_t FTDIDevice::ResetDevice() { TRACE_FUNCALLS("> FTDIDevice::ResetDevice(0x%08x)\n", this); size_t length = 0; status_t status = gUSBModule->send_request(Device(), USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, FTDI_PIT_DEFAULT, 0, NULL, &length); TRACE_FUNCRET("< FTDIDevice::ResetDevice() returns:%08x\n", status); return status; }
static status_t xet_nt_register(bool is_read, usb_vision_device *uvd, xet_nt100x_reg *ri) { status_t status = B_ERROR; //uint8 req_type = USB_REQTYPE_VENDOR | (is_read ? USB_REQTYPE_DEVICE_IN : USB_REQTYPE_DEVICE_OUT); TRACE_FUNCALLS("set_nt_register:%08x, %08x\n", uvd, ri); TRACE_FUNCRES(trace_reginfo, ri); //(*usb->send_request)(uvd->dev, req_type, // ) TRACE_FUNCRET("set_nt_register returns:%08x\n", status); return status; }
status_t ProlificDevice::ResetDevice() { TRACE_FUNCALLS("> ProlificDevice::ResetDevice(%08x)\n", this); SendRequestList(prolific_reset_common, B_COUNT_OF(prolific_reset_common)); if (fIsHX) SendRequestList(prolific_reset_common_hx, B_COUNT_OF(prolific_reset_common_hx)); else SendRequestList(prolific_reset_common_nhx, B_COUNT_OF(prolific_reset_common_nhx)); status_t status = B_OK; /* discard */ TRACE_FUNCRET("< ProlificDevice::ResetDevice() returns: 0x%08x\n", status); return status; }
bool usb_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags) { TRACE_FUNCALLS("> usb_serial_service(0x%08x, 0x%08x, 0x%08x)\n", ptty, ddr, flags); for (int32 i = 0; i < DEVICES_COUNT; i++) { if (gSerialDevices[i] && gSerialDevices[i]->Service(ptty, ddr, flags)) { TRACE_FUNCRET("< usb_serial_service() returns: true\n"); return true; } } TRACE_FUNCRET("< usb_serial_service() returns: false\n"); return false; }
bool usb_serial_service(struct tty *tty, uint32 op, void *buffer, size_t length) { TRACE_FUNCALLS("> usb_serial_service(%p, 0x%08lx, %p, %lu)\n", tty, op, buffer, length); for (int32 i = 0; i < DEVICES_COUNT; i++) { if (gSerialDevices[i] && gSerialDevices[i]->Service(tty, op, buffer, length)) { TRACE_FUNCRET("< usb_serial_service() returns: true\n"); return true; } } TRACE_FUNCRET("< usb_serial_service() returns: false\n"); return false; }
/* find_device - return poiter to device hooks structure for a given device */ device_hooks * find_device(const char *name) { static device_hooks deviceHooks = { usb_serial_open, /* -> open entry point */ usb_serial_close, /* -> close entry point */ usb_serial_free, /* -> free cookie */ usb_serial_control, /* -> control entry point */ usb_serial_read, /* -> read entry point */ usb_serial_write, /* -> write entry point */ usb_serial_select, /* -> select entry point */ usb_serial_deselect /* -> deselect entry point */ }; TRACE_FUNCALLS("> find_device(%s)\n", name); return &deviceHooks; }
/* usb_vision_control - handle ioctl calls */ static status_t usb_vision_control (void* cookie, uint32 op, void* arg, size_t len) { status_t status = B_BAD_VALUE; TRACE_FUNCALLS("usb_vision_control:%08x, %d, %08x, %d\n", cookie, op, arg, len); switch(op){ case NT_IOCTL_READ_REGISTER: status = xet_nt_register(true, (usb_vision_device *)cookie, (xet_nt100x_reg *) arg); break; case NT_IOCTL_WRITE_REGISTER: status = xet_nt_register(false, (usb_vision_device *)cookie, (xet_nt100x_reg *) arg); break; default: break; } TRACE_FUNCRET("usb_vision_control returns:%08x\n", status); return status; }
/* usb_serial_open - handle open() calls */ static status_t usb_serial_open(const char *name, uint32 flags, void **cookie) { TRACE_FUNCALLS("> usb_serial_open(%s, 0x%08x, 0x%08x)\n", name, flags, cookie); acquire_sem(gDriverLock); status_t status = ENODEV; *cookie = NULL; int i = strtol(name + strlen(sDeviceBaseName), NULL, 10); if (i >= 0 && i < DEVICES_COUNT && gSerialDevices[i]) { status = gSerialDevices[i]->Open(flags); *cookie = gSerialDevices[i]; } release_sem(gDriverLock); TRACE_FUNCRET("< usb_serial_open() returns: 0x%08x\n", status); return status; }
/* find_device - return poiter to device hooks structure for a given device */ device_hooks * find_device(const char *name) { static device_hooks deviceHooks = { usb_serial_open, /* -> open entry point */ usb_serial_close, /* -> close entry point */ usb_serial_free, /* -> free cookie */ usb_serial_control, /* -> control entry point */ usb_serial_read, /* -> read entry point */ usb_serial_write, /* -> write entry point */ #if defined(B_BEOS_VERSION_DANO) || defined(__ANTARES__) usb_serial_select, /* -> select entry point */ usb_serial_deselect /* -> deselect entry point */ #endif }; TRACE_FUNCALLS("> find_device(%s)\n", name); return &deviceHooks; }
void SerialDevice::InterruptCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength) { TRACE_FUNCALLS("interrupt callback: cookie: 0x%08x status: 0x%08x data: 0x%08x len: %lu\n", cookie, status, data, actualLength); SerialDevice *device = (SerialDevice *)cookie; device->fActualLengthInterrupt = actualLength; device->fStatusInterrupt = status; // ToDo: maybe handle those somehow? if (status == B_OK && !device->fDeviceRemoved) { status = gUSBModule->queue_interrupt(device->fControlPipe, device->fInterruptBuffer, device->fInterruptBufferSize, device->InterruptCallbackFunction, device); } }