Fix sending data with prolific devices. Seems they weren't initialised correctly. We now send the same stuff Linux does (without telling why), and it seems to work.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20493 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -133,6 +133,7 @@ struct _s_usb_serial_device{
|
||||
struct _spec_acm{ /* ACM-compatible devices */
|
||||
}acm;
|
||||
struct _spec_prolific{ /* Prolific devices*/
|
||||
bool is_HX; /* Linux handles HX type differently */
|
||||
}prolific;
|
||||
struct _spec_ftdi{ /* FTDI devices*/
|
||||
uint8 hdrlen;
|
||||
|
||||
@@ -18,18 +18,30 @@ status_t add_prolific_device(usb_serial_device *usd,
|
||||
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;
|
||||
int i = 0;
|
||||
|
||||
TRACE_FUNCALLS("> add_prolific_device(%08x, %08x)\n", usd, uci);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
if ((ddesc = (*usb_m->get_device_descriptor)(usd->dev))){
|
||||
usd->spec.prolific.is_HX = (ddesc->device_class != 0x02 &&
|
||||
ddesc->max_packet_size_0 == 0x40);
|
||||
}
|
||||
|
||||
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*/
|
||||
== USB_EP_ADDR_DIR_IN /*USB_EP_ADDR_DIR_OUT = 0x0*/){
|
||||
TRACE("add_prolific_device:comm endpoint at %d\n", i);
|
||||
comm_epi = &uii->endpoint[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
/*They say that USB-RSAQ1 has 2 interfaces */
|
||||
@@ -41,10 +53,12 @@ status_t add_prolific_device(usb_serial_device *usd,
|
||||
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_prolific_device:in endpoint at %d\n", i);
|
||||
data_in_epi = &uii->endpoint[i];
|
||||
}else{
|
||||
if(uii->endpoint[i].descr->endpoint_address
|
||||
/*USB_EP_ADDR_DIR_OUT = 0x0*/){
|
||||
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||
== USB_EP_ADDR_DIR_OUT){
|
||||
TRACE("add_prolific_device:out endpoint at %d\n", i);
|
||||
data_out_epi = &uii->endpoint[i];
|
||||
}
|
||||
}
|
||||
@@ -63,13 +77,72 @@ status_t add_prolific_device(usb_serial_device *usd,
|
||||
return status;
|
||||
}
|
||||
|
||||
struct req_item {
|
||||
uint8 requestType;
|
||||
uint8 request;
|
||||
uint16 value;
|
||||
uint16 index;
|
||||
};
|
||||
|
||||
#define PLRT_O (USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT)
|
||||
#define PLRT_I (USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN)
|
||||
|
||||
/* Linux sends all those, and it seems to work for me */
|
||||
/* see drivers/usb/serial/pl2303.c */
|
||||
static struct req_item pl_reset_common_reqs[] = {
|
||||
{PLRT_I, PROLIFIC_SET_REQUEST, 0x8484, 0},
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 0x0404, 0},
|
||||
{PLRT_I, PROLIFIC_SET_REQUEST, 0x8484, 0},
|
||||
{PLRT_I, PROLIFIC_SET_REQUEST, 0x8383, 0},
|
||||
{PLRT_I, PROLIFIC_SET_REQUEST, 0x8484, 0},
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 0x0404, 1},
|
||||
{PLRT_I, PROLIFIC_SET_REQUEST, 0x8484, 0},
|
||||
{PLRT_I, PROLIFIC_SET_REQUEST, 0x8383, 0},
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 0x0000, 1},
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 0x0001, 0}
|
||||
};
|
||||
static struct req_item pl_reset_common_hx[] = {
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 2, 0x44},
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 8, 0},
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 0, 0}
|
||||
};
|
||||
static struct req_item pl_reset_common_nhx[] = {
|
||||
{PLRT_O, PROLIFIC_SET_REQUEST, 2, 0x24}
|
||||
};
|
||||
|
||||
static status_t usb_send_requ_list(const usb_device *dev, struct req_item *list, size_t len){
|
||||
char buf[10];
|
||||
int i;
|
||||
status_t status;
|
||||
for (i = 0; i < len; i++){
|
||||
bool o = (list[i].requestType == PLRT_O);
|
||||
size_t len = 1;
|
||||
status = (*usb_m->send_request)(dev,
|
||||
list[i].requestType,
|
||||
list[i].request,
|
||||
list[i].value,
|
||||
list[i].index,
|
||||
0, o?0:buf, o?0:len, &len);
|
||||
TRACE("usb_send_requ_list: reqs[%d]: %08lx\n", i, status);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t reset_prolific_device(usb_serial_device *usd){
|
||||
status_t status;
|
||||
size_t len = 0;
|
||||
TRACE_FUNCALLS("> reset_prolific_device(%08x)\n", usd);
|
||||
status = (*usb_m->send_request)(usd->dev,
|
||||
/* status = (*usb_m->send_request)(usd->dev,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
PROLIFIC_SET_REQUEST, 0, 0, 0, 0, 0, &len);
|
||||
*/
|
||||
|
||||
usb_send_requ_list(usd->dev, pl_reset_common_reqs, SIZEOF(pl_reset_common_reqs));
|
||||
if (usd->spec.prolific.is_HX)
|
||||
usb_send_requ_list(usd->dev, pl_reset_common_hx, SIZEOF(pl_reset_common_hx));
|
||||
else
|
||||
usb_send_requ_list(usd->dev, pl_reset_common_nhx, SIZEOF(pl_reset_common_nhx));
|
||||
|
||||
TRACE_FUNCRET("< reset_prolific_device returns:%08x\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user