This should support KLSI KL5KUSB105D based adapters, like that usb-to-serial Palm (for use with serial craddle) I got here.
If I understood the linux driver correctly it should work but it seems I didn't yet :) For now it only lights the Terminal Ready light on my modem, doesn't get any data sent. Is it me or the semantics with the on_write() hook is broken ? (it's made to add headers/footers to buffers, but then header size is counted as written data, while it's not data as sent to the driver...) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21522 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -12,6 +12,7 @@ KernelAddon usb_serial :
|
||||
acm.c
|
||||
prolific.c
|
||||
ftdi.c
|
||||
klsi.c
|
||||
;
|
||||
|
||||
AddResources usb_serial : usb_serial.rdef ;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "acm.h"
|
||||
#include "prolific.h"
|
||||
#include "ftdi.h"
|
||||
#include "klsi.h"
|
||||
|
||||
/* driver callbacks forward declarations */
|
||||
static status_t usb_serial_open (const char *name, uint32 flags, void** cookie);
|
||||
@@ -132,6 +133,18 @@ usb_serial_hw usb_serial_hw_devices[] = {
|
||||
set_line_coding_ftdi, set_control_line_state_ftdi,
|
||||
on_read_ftdi, on_write_ftdi, on_close_ftdi,
|
||||
"FTDI 8U232AM serial converter"},
|
||||
|
||||
{VND_PALM, PROD_PALM_CONNECT,
|
||||
add_klsi_device, reset_klsi_device,
|
||||
set_line_coding_klsi, set_control_line_state_klsi,
|
||||
on_read_klsi, on_write_klsi, on_close_klsi,
|
||||
"PalmConnect RS232"},
|
||||
{VND_KLSI, PROD_KLSI_KL5KUSB105D,
|
||||
add_klsi_device, reset_klsi_device,
|
||||
set_line_coding_klsi, set_control_line_state_klsi,
|
||||
on_read_klsi, on_write_klsi, on_close_klsi,
|
||||
"KLSI KL5KUSB105D"},
|
||||
|
||||
};
|
||||
/* supported devices*/
|
||||
usb_support_descriptor *supported_devices;
|
||||
|
||||
@@ -144,6 +144,8 @@ struct _s_usb_serial_device{
|
||||
uint8 status_msr;
|
||||
uint8 status_lsr;
|
||||
}ftdi;
|
||||
struct _spec_klsi{ /* KLSI/PalmConnect */
|
||||
}klsi;
|
||||
}spec;
|
||||
}; /*already typedef-ed - see comment above! */
|
||||
/* high-level of abstraction of the device*/
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2003 by Siarzhuk Zharski <[email protected]>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <KernelExport.h>
|
||||
#include <Drivers.h>
|
||||
#include <USB.h>
|
||||
#include <ttylayer.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "klsi.h"
|
||||
|
||||
status_t add_klsi_device(usb_serial_device *usd,
|
||||
const usb_configuration_info *uci)
|
||||
{
|
||||
struct usb_endpoint_info *comm_epi = NULL;
|
||||
struct usb_endpoint_info *data_out_epi = NULL;
|
||||
struct usb_endpoint_info *data_in_epi = NULL;
|
||||
const usb_device_descriptor *ddesc;
|
||||
status_t status = ENODEV;
|
||||
uint32 i = 0;
|
||||
|
||||
TRACE_FUNCALLS("> add_klsi_device(%08x, %08x)\n", usd, uci);
|
||||
|
||||
if(uci->interface_count){
|
||||
struct usb_interface_info *uii = uci->interface[0].active;
|
||||
for(i = 0; i < uii->endpoint_count; i++){
|
||||
if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_INTERRUPT){
|
||||
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||
== USB_EP_ADDR_DIR_IN /*USB_EP_ADDR_DIR_OUT = 0x0*/){
|
||||
TRACE("add_klsi_device:comm endpoint at %d\n", i);
|
||||
comm_epi = &uii->endpoint[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < uii->endpoint_count; i++){
|
||||
if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_BULK){
|
||||
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||
== USB_EP_ADDR_DIR_IN){
|
||||
TRACE("add_klsi_device:in endpoint at %d\n", i);
|
||||
data_in_epi = &uii->endpoint[i];
|
||||
// usd->read_buffer_size = uii->endpoint[i].descr->max_packet_size;
|
||||
}else{
|
||||
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||
== USB_EP_ADDR_DIR_OUT){
|
||||
TRACE("add_klsi_device:out endpoint at %d\n", i);
|
||||
data_out_epi = &uii->endpoint[i];
|
||||
// usd->write_buffer_size = uii->endpoint[i].descr->max_packet_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(comm_epi && data_in_epi && data_out_epi){
|
||||
usd->read_buffer_size =
|
||||
usd->write_buffer_size =
|
||||
usd->interrupt_buffer_size = ROUNDUP(KLSI_BUF_SIZE, 16);
|
||||
status = add_device(usd, uci, comm_epi, data_out_epi, data_in_epi);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_FUNCRET("< add_klsi_device returns:%08x\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t reset_klsi_device(usb_serial_device *usd){
|
||||
status_t status;
|
||||
size_t len = 0;
|
||||
TRACE_FUNCALLS("> reset_klsi_device(%08x)\n", usd);
|
||||
|
||||
status = (*usb_m->send_request)(usd->dev,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_INTERFACE_OUT,
|
||||
KLSI_CONF_REQUEST,
|
||||
KLSI_CONF_REQUEST_READ_ON, 0, 0,
|
||||
0, 0, &len);
|
||||
TRACE_FUNCRET("< reset_klsi_device returns:%08x\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t set_line_coding_klsi(usb_serial_device *usd,
|
||||
usb_serial_line_coding *line_coding){
|
||||
status_t status = B_OK;
|
||||
uint8 rate;
|
||||
size_t len1 = 0, len2 = 0;
|
||||
uint8 coding_packet[5];
|
||||
TRACE_FUNCALLS("> set_line_coding_klsi(%08x, {%d, %02x, %02x, %02x})\n",
|
||||
usd, line_coding->speed,
|
||||
line_coding->stopbits,
|
||||
line_coding->parity,
|
||||
line_coding->databits);
|
||||
|
||||
coding_packet[0] = 5; /* size */
|
||||
switch (line_coding->speed){
|
||||
case 300: rate = klsi_sio_b300; break;
|
||||
case 600: rate = klsi_sio_b600; break;
|
||||
case 1200: rate = klsi_sio_b1200; break;
|
||||
case 2400: rate = klsi_sio_b2400; break;
|
||||
case 4800: rate = klsi_sio_b4800; break;
|
||||
case 9600: rate = klsi_sio_b9600; break;
|
||||
case 19200: rate = klsi_sio_b19200; break;
|
||||
case 38400: rate = klsi_sio_b38400; break;
|
||||
case 57600: rate = klsi_sio_b57600; break;
|
||||
case 115200: rate = klsi_sio_b115200; break;
|
||||
default:
|
||||
rate = klsi_sio_b19200;
|
||||
TRACE_ALWAYS("= set_line_coding_klsi: Datarate:%d is not supported "
|
||||
"by this hardware. Defaulted to %d\n",
|
||||
line_coding->speed, rate);
|
||||
break;
|
||||
}
|
||||
coding_packet[1] = rate;
|
||||
/* only 7,8 */
|
||||
coding_packet[2] = line_coding->databits;
|
||||
/* unknown */
|
||||
coding_packet[3] = 0;
|
||||
coding_packet[4] = 1;
|
||||
|
||||
status = (*usb_m->send_request)(usd->dev,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_INTERFACE_OUT,
|
||||
KLSI_SET_REQUEST, 0, 0, 0,
|
||||
coding_packet, sizeof(coding_packet), &len1);
|
||||
if(status != B_OK)
|
||||
TRACE_ALWAYS("= set_line_coding_ftdi: datarate set request failed:%08x",
|
||||
status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t set_control_line_state_klsi(usb_serial_device *usd, uint16 state){
|
||||
status_t status = B_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void on_read_klsi(usb_serial_device *usd, char **buf, size_t *num_bytes){
|
||||
size_t num;
|
||||
if (*num_bytes <= 2) {
|
||||
*num_bytes = 0;
|
||||
return;
|
||||
}
|
||||
num = B_LENDIAN_TO_HOST_INT16(*(uint16*)(*buf));
|
||||
*num_bytes = MIN(num, (*num_bytes - 2));
|
||||
*buf += 2;
|
||||
}
|
||||
|
||||
void on_write_klsi(usb_serial_device *usd, const char *buf, size_t *num_bytes){
|
||||
if(*num_bytes > usd->write_buffer_size)
|
||||
*num_bytes = usd->write_buffer_size;
|
||||
if(*num_bytes > 62)
|
||||
*num_bytes = 62;
|
||||
*num_bytes = 6;
|
||||
*((uint16*)usd->write_buffer) = B_HOST_TO_LENDIAN_INT16(*num_bytes);
|
||||
memcpy(usd->write_buffer+2, buf, *num_bytes);
|
||||
memcpy(usd->write_buffer+2, "ATDT0\n", 6);
|
||||
*num_bytes = 64;
|
||||
}
|
||||
|
||||
void on_close_klsi(usb_serial_device *usd){
|
||||
status_t status;
|
||||
size_t len = 0;
|
||||
TRACE_FUNCALLS("> on_close_klsi(%08x)\n", usd);
|
||||
status = (*usb_m->send_request)(usd->dev,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
KLSI_CONF_REQUEST,
|
||||
KLSI_CONF_REQUEST_READ_OFF, 0, 0,
|
||||
0, 0, &len);
|
||||
(*usb_m->cancel_queued_transfers)(usd->pipe_read);
|
||||
(*usb_m->cancel_queued_transfers)(usd->pipe_write);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2004 by Siarzhuk Zharski <[email protected]>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _USB_KLSI_H_
|
||||
#define _USB_KLSI_H_
|
||||
|
||||
#define VND_PALM 0x0830
|
||||
#define VND_KLSI 0x05e9
|
||||
|
||||
#define PROD_PALM_CONNECT 0x0080
|
||||
#define PROD_KLSI_KL5KUSB105D 0x00c0
|
||||
|
||||
#define KLSI_SET_REQUEST 0x01
|
||||
#define KLSI_POLL_REQUEST 0x02
|
||||
#define KLSI_CONF_REQUEST 0x03
|
||||
#define KLSI_CONF_REQUEST_READ_ON 0x03
|
||||
#define KLSI_CONF_REQUEST_READ_OFF 0x02
|
||||
|
||||
// not sure
|
||||
#define KLSI_BUF_SIZE 64
|
||||
|
||||
enum {
|
||||
klsi_sio_b115200 = 0,
|
||||
klsi_sio_b57600 = 1,
|
||||
klsi_sio_b38400 = 2,
|
||||
klsi_sio_b19200 = 4,
|
||||
klsi_sio_b9600 = 6,
|
||||
/* unchecked */
|
||||
klsi_sio_b4800 = 8,
|
||||
klsi_sio_b2400 = 9,
|
||||
klsi_sio_b1200 = 10,
|
||||
klsi_sio_b600 = 11,
|
||||
klsi_sio_b300 = 12,
|
||||
};
|
||||
|
||||
|
||||
status_t add_klsi_device(usb_serial_device *usd,
|
||||
const usb_configuration_info *uci);
|
||||
status_t reset_klsi_device(usb_serial_device *usd);
|
||||
status_t set_line_coding_klsi(usb_serial_device *usd,
|
||||
usb_serial_line_coding *line_coding);
|
||||
|
||||
status_t set_control_line_state_klsi(usb_serial_device *usd, uint16 state);
|
||||
void on_read_klsi(usb_serial_device *usd, char **buf, size_t *num_bytes);
|
||||
void on_write_klsi(usb_serial_device *usd, const char *buf, size_t *num_bytes);
|
||||
void on_close_klsi(usb_serial_device *usd);
|
||||
|
||||
#endif //_USB_PROLIFIC_H_
|
||||
Reference in New Issue
Block a user