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; }
/* 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; }
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; }
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; }
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; }
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; }
/* 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_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; status_t status = device->Read((char *)buffer, numBytes); TRACE_FUNCRET("< usb_serial_read() returns: 0x%08x\n", status); return status; }
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; }
/* 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; }
status_t FTDIDevice::AddDevice(const usb_configuration_info *config) { TRACE_FUNCALLS("> FTDIDevice::AddDevice(%08x, %08x)\n", this, config); status_t status = ENODEV; if (config->interface_count > 0) { int32 pipesSet = 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_BULK) { if (endpoint->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) { SetReadPipe(endpoint->handle); if (++pipesSet >= 3) break; } else { if (endpoint->descr->endpoint_address) { SetControlPipe(endpoint->handle); SetWritePipe(endpoint->handle); pipesSet += 2; if (pipesSet >= 3) break; } } } } if (pipesSet >= 3) { if (ProductID() == 0x8372) // AU100AX fHeaderLength = 1; else fHeaderLength = 0; status = B_OK; } } TRACE_FUNCRET("< FTDIDevice::AddDevice() returns: 0x%08x\n", status); return status; }
/* init_driver - called every time the driver is loaded. */ status_t init_driver() { load_settings(); create_log_file(); TRACE_FUNCALLS("> init_driver()\n"); status_t status = get_module(B_TTY_MODULE_NAME, (module_info **)&gTTYModule); if (status < B_OK) return status; status = get_module(B_USB_MODULE_NAME, (module_info **)&gUSBModule); if (status < B_OK) { put_module(B_TTY_MODULE_NAME); return status; } for (int32 i = 0; i < DEVICES_COUNT; i++) gSerialDevices[i] = NULL; gDeviceNames[0] = NULL; gDriverLock = create_sem(1, DRIVER_NAME"_devices_table_lock"); if (gDriverLock < B_OK) { put_module(B_USB_MODULE_NAME); put_module(B_TTY_MODULE_NAME); return gDriverLock; } static usb_notify_hooks notifyHooks = { &usb_serial_device_added, &usb_serial_device_removed }; gUSBModule->register_driver(DRIVER_NAME, NULL, 0, NULL); gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks); TRACE_FUNCRET("< init_driver() returns\n"); return B_OK; }
/* usb_serial_free - called after last device is closed, and all i/o complete. */ static status_t usb_serial_free(void *cookie) { TRACE_FUNCALLS("> usb_serial_free(0x%08x)\n", cookie); SerialDevice *device = (SerialDevice *)cookie; acquire_sem(gDriverLock); status_t status = device->Free(); if (device->IsRemoved()) { for (int32 i = 0; i < DEVICES_COUNT; i++) { if (gSerialDevices[i] == device) { // the device is removed already but as it was open the // removed hook has not deleted the object delete device; gSerialDevices[i] = NULL; break; } } } release_sem(gDriverLock); TRACE_FUNCRET("< usb_serial_free() returns: 0x%08x\n", status); return status; }
status_t usb_vision_device_removed(void *cookie){ int i; status_t status = B_OK; struct usb_device *ud = (struct usb_device *) cookie; TRACE_FUNCALLS("usb_vision_device_removed:%08x\n", cookie); acquire_sem(usb_vision_lock); for(i = 0; i < DEVICES_COUNT; i++ ){ usb_vision_device *uvd = usb_vision_devices[i]; if(uvd){ if(ud == uvd->dev){ free(uvd); usb_vision_devices[i] = 0; } } } release_sem(usb_vision_lock); TRACE_FUNCRET("usb_vision_device_removed returns:%08x\n", status); return status; }
status_t usb_vision_device_added(const usb_device *dev, void **cookie){ int dev_idx; status_t status = B_OK; const usb_device_descriptor *udd; usb_vision_device *uvd = 0; TRACE_FUNCALLS("usb_vision_device_added:%08x cookie:%08x\n", dev, cookie); udd = (*usb->get_device_descriptor)(dev); TRACE_ALWAYS("Probing device: %08x/%08x\n", udd->vendor_id, udd->product_id); *cookie = 0; for(dev_idx = 0; dev_idx < SIZEOF(supported_devices); dev_idx++) if(supported_devices[dev_idx].vendor == udd->vendor_id && supported_devices[dev_idx].product == udd->product_id){ const usb_configuration_info *uci; int cfg_idx; for(cfg_idx = 0; (uci = (*usb->get_nth_configuration)(dev, cfg_idx)) != NULL; cfg_idx++){ uvd = malloc(sizeof(usb_vision_device)); if(uvd){ memset(uvd, 0, sizeof(usb_vision_device)); uvd->dev = dev; if((status = add_device(uvd, uci)) == B_OK){ *cookie = (void *)dev; TRACE_ALWAYS("(%04x/%04x) added \n", supported_devices[dev_idx].vendor, supported_devices[dev_idx].product); break; }else free(uvd); }else status = B_NO_MEMORY; } break; } TRACE_FUNCRET("usb_vision_device_added returns:%08x\n", status); return status; }
/* uninit_driver - called every time the driver is unloaded */ void uninit_driver() { TRACE_FUNCALLS("> uninit_driver()\n"); gUSBModule->uninstall_notify(DRIVER_NAME); acquire_sem(gDriverLock); for (int32 i = 0; i < DEVICES_COUNT; i++) { if (gSerialDevices[i]) { delete gSerialDevices[i]; gSerialDevices[i] = NULL; } } for (int32 i = 0; gDeviceNames[i]; i++) free(gDeviceNames[i]); delete_sem(gDriverLock); put_module(B_USB_MODULE_NAME); put_module(B_TTY_MODULE_NAME); TRACE_FUNCRET("< uninit_driver() returns\n"); }
status_t FTDIDevice::SetLineCoding(usb_cdc_line_coding *lineCoding) { TRACE_FUNCALLS("> FTDIDevice::SetLineCoding(0x%08x, {%d, 0x%02x, 0x%02x, 0x%02x})\n", this, lineCoding->speed, lineCoding->stopbits, lineCoding->parity, lineCoding->databits); int32 rate = 0; if (ProductID() == 0x8372) { // AU100AX switch (lineCoding->speed) { case 300: rate = ftdi_sio_b300; break; case 600: rate = ftdi_sio_b600; break; case 1200: rate = ftdi_sio_b1200; break; case 2400: rate = ftdi_sio_b2400; break; case 4800: rate = ftdi_sio_b4800; break; case 9600: rate = ftdi_sio_b9600; break; case 19200: rate = ftdi_sio_b19200; break; case 38400: rate = ftdi_sio_b38400; break; case 57600: rate = ftdi_sio_b57600; break; case 115200: rate = ftdi_sio_b115200; break; default: rate = ftdi_sio_b19200; TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): Datarate: %d is " "not supported by this hardware. Defaulted to %d\n", lineCoding->speed, rate); break; } } else { switch (lineCoding->speed) { case 300: rate = ftdi_8u232am_b300; break; case 600: rate = ftdi_8u232am_b600; break; case 1200: rate = ftdi_8u232am_b1200; break; case 2400: rate = ftdi_8u232am_b2400; break; case 4800: rate = ftdi_8u232am_b4800; break; case 9600: rate = ftdi_8u232am_b9600; break; case 19200: rate = ftdi_8u232am_b19200; break; case 38400: rate = ftdi_8u232am_b38400; break; case 57600: rate = ftdi_8u232am_b57600; break; case 115200: rate = ftdi_8u232am_b115200; break; case 230400: rate = ftdi_8u232am_b230400; break; case 460800: rate = ftdi_8u232am_b460800; break; case 921600: rate = ftdi_8u232am_b921600; break; default: rate = ftdi_sio_b19200; TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): Datarate: %d is " "not supported by this hardware. Defaulted to %d\n", lineCoding->speed, rate); break; } } size_t length = 0; status_t status = gUSBModule->send_request(Device(), USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, FTDI_SIO_SET_BAUD_RATE, rate, FTDI_PIT_DEFAULT, 0, NULL, &length); if (status != B_OK) TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): datarate set request failed: 0x%08x\n", status); int32 data = 0; switch (lineCoding->stopbits) { case USB_CDC_LINE_CODING_1_STOPBIT: data = FTDI_SIO_SET_DATA_STOP_BITS_2; break; case USB_CDC_LINE_CODING_2_STOPBITS: data = FTDI_SIO_SET_DATA_STOP_BITS_1; break; default: TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): Wrong stopbits param: %d\n", lineCoding->stopbits); break; } switch (lineCoding->parity) { case USB_CDC_LINE_CODING_NO_PARITY: data |= FTDI_SIO_SET_DATA_PARITY_NONE; break; case USB_CDC_LINE_CODING_EVEN_PARITY: data |= FTDI_SIO_SET_DATA_PARITY_EVEN; break; case USB_CDC_LINE_CODING_ODD_PARITY: data |= FTDI_SIO_SET_DATA_PARITY_ODD; break; default: TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): Wrong parity param: %d\n", lineCoding->parity); break; } switch (lineCoding->databits) { case 8: data |= FTDI_SIO_SET_DATA_BITS(8); break; case 7: data |= FTDI_SIO_SET_DATA_BITS(7); break; default: TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): Wrong databits param: %d\n", lineCoding->databits); break; } length = 0; status = gUSBModule->send_request(Device(), USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, FTDI_SIO_SET_DATA, data, FTDI_PIT_DEFAULT, 0, NULL, &length); if (status != B_OK) TRACE_ALWAYS("= FTDIDevice::SetLineCoding(): data set request failed: %08x\n", status); TRACE_FUNCRET("< FTDIDevice::SetLineCoding() returns: 0x%08x\n", status); return status; }