1
0
Fork 0
forked from len0rd/rockbox

- change the usb class driver framework to allow for device classes with more than one interface or more than one endpoint pair

- move the charging-only dummy driver out of usb_core



git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17252 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Gevaerts 2008-04-26 19:02:16 +00:00
parent 33c44461e1
commit bec6aa3176
10 changed files with 279 additions and 152 deletions

View file

@ -235,6 +235,7 @@ drivers/audio/mas35xx.c
usbstack/usb_core.c
usbstack/usb_storage.c
usbstack/usb_serial.c
usbstack/usb_charging_only.c
#if CONFIG_USBOTG == USBOTG_ARC
target/arm/usb-drv-arc.c
#elif CONFIG_USBOTG == USBOTG_ISP1583

View file

@ -53,6 +53,7 @@ void usb_core_enable_driver(int driver,bool enabled);
bool usb_core_driver_enabled (int driver);
void usb_core_handle_transfer_completion(
struct usb_transfer_completion_event_data* event);
int usb_core_ack_control(struct usb_ctrlrequest* req);
#ifdef HAVE_HOTSWAP
void usb_core_hotswap_event(int volume,bool inserted);
#endif

View file

@ -0,0 +1,72 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: $
*
* Copyright (C) 2008 by Frank Gevaerts
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "string.h"
#include "system.h"
#include "usb_core.h"
#include "usb_drv.h"
#include "kernel.h"
//#define LOGF_ENABLE
#include "logf.h"
#ifdef USB_CHARGING_ONLY
/* charging_only interface */
static struct usb_interface_descriptor __attribute__((aligned(2)))
interface_descriptor =
{
.bLength = sizeof(struct usb_interface_descriptor),
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0
};
static int usb_interface;
int usb_charging_only_set_first_endpoint(int endpoint)
{
/* The dummy charging_only driver doesn't need an endpoint pair */
return endpoint;
}
int usb_charging_only_set_first_interface(int interface)
{
usb_interface = interface;
return interface + 1;
}
int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size)
{
(void)max_packet_size;
unsigned char *orig_dest = dest;
interface_descriptor.bInterfaceNumber=usb_interface;
memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
dest+=sizeof(struct usb_interface_descriptor);
return (dest-orig_dest);
}
#endif /*USB_CHARGING_ONLY*/

View file

@ -0,0 +1,31 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: $
*
* Copyright (C) 2008 by Frank Gevaerts
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef USB_CHARGING_ONLY_H
#define USB_CHARGING_ONLY_H
#include "usb_ch9.h"
void usb_charging_only_init(void);
int usb_charging_only_set_first_endpoint(int endpoint);
int usb_charging_only_set_first_interface(int interface);
int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size);
bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
#endif

View file

@ -23,41 +23,65 @@
/* Common api, implemented by all class drivers */
struct usb_class_driver {
/* First some runtime data */
bool enabled;
int first_interface;
int last_interface;
/* Driver api starts here */
/* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
bool needs_exclusive_ata;
int usb_endpoint;
int usb_interface;
/* Tells the driver what its first interface number will be. The driver
returns the number of the first available interface for the next driver
(i.e. a driver with one interface will return interface+1)
A driver must have at least one interface
Mandatory function */
int (*set_first_interface)(int interface);
/* Tells the driver what its first endpoint pair number will be. The driver
returns the number of the first available endpoint pair for the next
driver (i.e. a driver with one endpoint pair will return endpoint +1)
Mandatory function */
int (*set_first_endpoint)(int endpoint);
/* Asks the driver to put the interface descriptor and all other
needed descriptor for this driver at dest, for the given settings.
Returns the number of bytes taken by these descriptors. */
int (*get_config_descriptor)(unsigned char *dest,
int max_packet_size, int interface_number, int endpoint);
needed descriptor for this driver at dest.
Returns the number of bytes taken by these descriptors.
Mandatory function */
int (*get_config_descriptor)(unsigned char *dest, int max_packet_size);
/* Tells the driver that a usb connection has been set up and is now
ready to use. */
void (*init_connection)(int interface,int endpoint);
ready to use.
Optional function */
void (*init_connection)(void);
/* Initialises the driver. This can be called multiple times,
and should not perform any action that can disturb other threads
(like getting the audio buffer) */
(like getting the audio buffer)
Optional function */
void (*init)(void);
/* Tells the driver that the usb connection is no longer active */
/* Tells the driver that the usb connection is no longer active
Optional function */
void (*disconnect)(void);
/* Tells the driver that a usb transfer has been completed. Note that "in"
is relative to the host */
void (*transfer_complete)(bool in, int status, int length);
is relative to the host
Optional function */
void (*transfer_complete)(int ep,bool in, int status, int length);
/* Tells the driver that a control request has come in. If the driver is
able to handle it, it should ack the request, and return true. Otherwise
it should return false. */
it should return false.
Optional function */
bool (*control_request)(struct usb_ctrlrequest* req);
#ifdef HAVE_HOTSWAP
/* Tells the driver that a hotswappable disk/card was inserted or
extracted */
extracted
Optional function */
void (*notify_hotswap)(int volume, bool inserted);
#endif
};

View file

@ -37,6 +37,10 @@
#include "usb_serial.h"
#endif
#if defined(USB_CHARGING_ONLY)
#include "usb_charging_only.h"
#endif
/* TODO: Move target-specific stuff somewhere else (serial number reading) */
#ifdef HAVE_AS3514
@ -91,22 +95,6 @@ static struct usb_config_descriptor __attribute__((aligned(2)))
.bMaxPower = 250, /* 500mA in 2mA units */
};
#ifdef USB_CHARGING_ONLY
/* dummy interface for charging-only */
static struct usb_interface_descriptor __attribute__((aligned(2)))
charging_interface_descriptor =
{
.bLength = sizeof(struct usb_interface_descriptor),
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 4
};
#endif
static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
qualifier_descriptor =
@ -160,21 +148,12 @@ static const struct usb_string_descriptor __attribute__((aligned(2)))
{0x0409} /* LANGID US English */
};
static const struct usb_string_descriptor __attribute__((aligned(2)))
usb_string_charging_only =
{
28,
USB_DT_STRING,
{'C','h','a','r','g','i','n','g',' ','o','n','l','y'}
};
static const struct usb_string_descriptor* const usb_strings[] =
{
&lang_descriptor,
&usb_string_iManufacturer,
&usb_string_iProduct,
&usb_string_iSerial,
&usb_string_charging_only
&usb_string_iSerial
};
static int usb_address = 0;
@ -183,8 +162,12 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
static int usb_core_num_interfaces;
static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
int interface_number,int endpoint);
static struct
{
void (*completion_handler)(int ep,bool in, int status, int length);
bool (*control_handler)(struct usb_ctrlrequest* req);
struct usb_transfer_completion_event_data completion_event;
} ep_data[NUM_ENDPOINTS];
static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
{
@ -192,8 +175,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
[USB_DRIVER_MASS_STORAGE] = {
.enabled = false,
.needs_exclusive_ata = true,
.usb_endpoint = 0,
.usb_interface = 0,
.first_interface = 0,
.last_interface = 0,
.set_first_interface = usb_storage_set_first_interface,
.set_first_endpoint = usb_storage_set_first_endpoint,
.get_config_descriptor = usb_storage_get_config_descriptor,
.init_connection = usb_storage_init_connection,
.init = usb_storage_init,
@ -209,8 +194,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
[USB_DRIVER_SERIAL] = {
.enabled = false,
.needs_exclusive_ata = false,
.usb_endpoint = 0,
.usb_interface = 0,
.first_interface = 0,
.last_interface = 0,
.set_first_interface = usb_serial_set_first_interface,
.set_first_endpoint = usb_serial_set_first_endpoint,
.get_config_descriptor = usb_serial_get_config_descriptor,
.init_connection = usb_serial_init_connection,
.init = usb_serial_init,
@ -226,9 +213,11 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
[USB_DRIVER_CHARGING_ONLY] = {
.enabled = false,
.needs_exclusive_ata = false,
.usb_endpoint = 0,
.usb_interface = 0,
.get_config_descriptor = usb_charging_get_config_descriptor,
.first_interface = 0,
.last_interface = 0,
.set_first_interface = usb_charging_only_set_first_interface,
.set_first_endpoint = usb_charging_only_set_first_endpoint,
.get_config_descriptor = usb_charging_only_get_config_descriptor,
.init_connection = NULL,
.init = NULL,
.disconnect = NULL,
@ -242,11 +231,9 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
};
static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
static int ack_control(struct usb_ctrlrequest* req);
static unsigned char response_data[256] USBDEVBSS_ATTR;
static struct usb_transfer_completion_event_data events[NUM_ENDPOINTS];
static short hex[16] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
@ -331,17 +318,6 @@ void usb_core_init(void)
logf("usb_core_init() finished");
}
static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
int interface_number,int endpoint)
{
(void) max_packet_size;
(void) endpoint;
charging_interface_descriptor.bInterfaceNumber=interface_number;
memcpy(dest,&charging_interface_descriptor,
sizeof(struct usb_interface_descriptor));
return sizeof(struct usb_interface_descriptor);
}
void usb_core_exit(void)
{
int i;
@ -360,27 +336,20 @@ void usb_core_exit(void)
void usb_core_handle_transfer_completion(
struct usb_transfer_completion_event_data* event)
{
int i;
switch(event->endpoint) {
int ep = event->endpoint;
switch(ep) {
case EP_CONTROL:
logf("ctrl handled %ld",current_tick);
usb_core_control_request_handler(
(struct usb_ctrlrequest*)event->data);
break;
default:
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled &&
drivers[i].usb_endpoint == event->endpoint &&
drivers[i].transfer_complete != NULL)
{
drivers[i].transfer_complete(event->in,
if(ep_data[ep].completion_handler != NULL)
ep_data[ep].completion_handler(ep,event->in,
event->status,event->length);
break;
}
}
break;
}
}
void usb_core_enable_driver(int driver,bool enabled)
{
@ -419,13 +388,29 @@ static void usb_core_set_serial_function_id(void)
static void allocate_interfaces_and_endpoints(void)
{
int i;
int i,j;
int interface=0;
int endpoint=1;
memset(ep_data,0,sizeof(ep_data));
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled) {
drivers[i].usb_endpoint = endpoint++;
drivers[i].usb_interface = interface++;
int oldendpoint = endpoint;
drivers[i].first_interface = interface;
endpoint = drivers[i].set_first_endpoint(endpoint);
if(endpoint>NUM_ENDPOINTS) {
drivers[i].enabled = false;
continue;
}
interface = drivers[i].set_first_interface(interface);
drivers[i].last_interface = interface;
for(j=oldendpoint;j<endpoint;j++) {
ep_data[j].completion_handler=drivers[i].transfer_complete;
ep_data[j].control_handler=drivers[i].control_request;
}
}
if(endpoint>NUM_ENDPOINTS) {
drivers[i].enabled = false;
@ -463,7 +448,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[0] = 1;
if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
break;
ack_control(req);
usb_core_ack_control(req);
break;
case USB_REQ_SET_CONFIGURATION:
logf("usb_core: SET_CONFIG");
@ -474,22 +459,20 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
if(drivers[i].enabled &&
drivers[i].init_connection!=NULL)
{
drivers[i].init_connection(
drivers[i].usb_interface,
drivers[i].usb_endpoint);
drivers[i].init_connection();
}
}
}
else {
usb_state = ADDRESS;
}
ack_control(req);
usb_core_ack_control(req);
break;
}
case USB_REQ_SET_ADDRESS: {
unsigned char address = req->wValue;
logf("usb_core: SET_ADR %d", address);
if(ack_control(req)!=0)
if(usb_core_ack_control(req)!=0)
break;
usb_drv_cancel_all_transfers();
usb_address = address;
@ -537,9 +520,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
{
size+=drivers[i].get_config_descriptor(
&response_data[size],
max_packet_size,
drivers[i].usb_interface,
drivers[i].usb_endpoint);
max_packet_size);
}
}
config_descriptor.bNumInterfaces =
@ -587,7 +568,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
if(usb_drv_send(EP_CONTROL, response_data, length)!=0)
break;
}
ack_control(req);
usb_core_ack_control(req);
break;
} /* USB_REQ_GET_DESCRIPTOR */
case USB_REQ_CLEAR_FEATURE:
@ -595,7 +576,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
case USB_REQ_SET_FEATURE:
if(req->wValue == 2) { /* TEST_MODE */
int mode=req->wIndex>>8;
ack_control(req);
usb_core_ack_control(req);
usb_drv_set_test_mode(mode);
}
break;
@ -604,7 +585,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[1]= 0;
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
break;
ack_control(req);
usb_core_ack_control(req);
break;
default:
break;
@ -614,7 +595,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
logf("usb_core: SET_INTERFACE");
ack_control(req);
usb_core_ack_control(req);
break;
case USB_REQ_GET_INTERFACE:
@ -622,7 +603,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[0] = 0;
if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
break;
ack_control(req);
usb_core_ack_control(req);
break;
case USB_REQ_CLEAR_FEATURE:
break;
@ -633,14 +614,15 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
response_data[1]= 0;
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
break;
ack_control(req);
usb_core_ack_control(req);
break;
default: {
bool handled=false;
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled &&
drivers[i].control_request &&
drivers[i].usb_interface == (req->wIndex))
drivers[i].first_interface <= (req->wIndex) &&
drivers[i].last_interface > (req->wIndex))
{
handled = drivers[i].control_request(req);
}
@ -649,7 +631,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
/* nope. flag error */
logf("usb bad req %d", req->bRequest);
usb_drv_stall(EP_CONTROL, true,true);
ack_control(req);
usb_core_ack_control(req);
}
break;
}
@ -661,13 +643,13 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
if (req->wValue == 0 ) /* ENDPOINT_HALT */
usb_drv_stall(req->wIndex & 0xf, false,
(req->wIndex & 0x80) !=0);
ack_control(req);
usb_core_ack_control(req);
break;
case USB_REQ_SET_FEATURE:
if (req->wValue == 0 ) /* ENDPOINT_HALT */
usb_drv_stall(req->wIndex & 0xf, true,
(req->wIndex & 0x80) !=0);
ack_control(req);
usb_core_ack_control(req);
break;
case USB_REQ_GET_STATUS:
response_data[0]= 0;
@ -678,23 +660,17 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
(req->wIndex&0x80)!=0);
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
break;
ack_control(req);
usb_core_ack_control(req);
break;
default: {
bool handled=false;
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled &&
drivers[i].control_request &&
drivers[i].usb_endpoint == (req->wIndex & 0xf))
{
handled = drivers[i].control_request(req);
}
}
if(ep_data[req->wIndex & 0xf].control_handler != NULL)
handled = ep_data[req->wIndex & 0xf].control_handler(req);
if(!handled) {
/* nope. flag error */
logf("usb bad req %d", req->bRequest);
usb_drv_stall(EP_CONTROL, true,true);
ack_control(req);
usb_core_ack_control(req);
}
break;
}
@ -719,13 +695,13 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
break;
default:
events[endpoint].endpoint=endpoint;
events[endpoint].in=in;
events[endpoint].data=0;
events[endpoint].status=status;
events[endpoint].length=length;
ep_data[endpoint].completion_event.endpoint=endpoint;
ep_data[endpoint].completion_event.in=in;
ep_data[endpoint].completion_event.data=0;
ep_data[endpoint].completion_event.status=status;
ep_data[endpoint].completion_event.length=length;
/* All other endoints. Let the thread deal with it */
usb_signal_transfer_completion(&events[endpoint]);
usb_signal_transfer_completion(&ep_data[endpoint].completion_event);
break;
}
}
@ -733,16 +709,16 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
/* called by usb_drv_int() */
void usb_core_control_request(struct usb_ctrlrequest* req)
{
events[0].endpoint=0;
events[0].in=0;
events[0].data=(void *)req;
events[0].status=0;
events[0].length=0;
ep_data[0].completion_event.endpoint=0;
ep_data[0].completion_event.in=0;
ep_data[0].completion_event.data=(void *)req;
ep_data[0].completion_event.status=0;
ep_data[0].completion_event.length=0;
logf("ctrl received %ld",current_tick);
usb_signal_transfer_completion(&events[0]);
usb_signal_transfer_completion(&ep_data[0].completion_event);
}
static int ack_control(struct usb_ctrlrequest* req)
int usb_core_ack_control(struct usb_ctrlrequest* req)
{
if (req->bRequestType & 0x80)
return usb_drv_recv(EP_CONTROL, NULL, 0);

View file

@ -28,7 +28,7 @@
#ifdef USB_SERIAL
/* serial interface */
struct usb_interface_descriptor __attribute__((aligned(2)))
static struct usb_interface_descriptor __attribute__((aligned(2)))
interface_descriptor =
{
.bLength = sizeof(struct usb_interface_descriptor),
@ -42,7 +42,8 @@ struct usb_interface_descriptor __attribute__((aligned(2)))
.iInterface = 0
};
struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
static struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
{
.bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = USB_DT_ENDPOINT,
@ -90,31 +91,42 @@ static void sendout(void)
busy_sending=true;
}
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
int interface_number,int endpoint)
int usb_serial_set_first_endpoint(int endpoint)
{
endpoint_descriptor.wMaxPacketSize=max_packet_size;
interface_descriptor.bInterfaceNumber=interface_number;
usb_endpoint = endpoint;
return endpoint + 1;
}
int usb_serial_set_first_interface(int interface)
{
usb_interface = interface;
return interface + 1;
}
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size)
{
unsigned char *orig_dest = dest;
endpoint_descriptor.wMaxPacketSize=max_packet_size;
interface_descriptor.bInterfaceNumber=usb_interface;
memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
dest+=sizeof(struct usb_interface_descriptor);
endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN,
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
dest+=sizeof(struct usb_endpoint_descriptor);
endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT,
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
return sizeof(struct usb_interface_descriptor) +
2 * sizeof(struct usb_endpoint_descriptor);
dest+=sizeof(struct usb_endpoint_descriptor);
return (dest - orig_dest);
}
void usb_serial_init_connection(int interface,int endpoint)
void usb_serial_init_connection(void)
{
usb_interface = interface;
usb_endpoint = endpoint;
/* prime rx endpoint */
usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer);
@ -187,8 +199,9 @@ void usb_serial_send(unsigned char *data,int length)
}
/* called by usb_core_transfer_complete() */
void usb_serial_transfer_complete(bool in, int status, int length)
void usb_serial_transfer_complete(int ep,bool in, int status, int length)
{
(void)ep;
switch (in) {
case false:
logf("serial: %s", receive_buffer);

View file

@ -21,12 +21,13 @@
#include "usb_ch9.h"
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
int interface_number, int endpoint);
void usb_serial_init_connection(int interface,int endpoint);
int usb_serial_set_first_endpoint(int endpoint);
int usb_serial_set_first_interface(int interface);
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size);
void usb_serial_init_connection(void);
void usb_serial_init(void);
void usb_serial_disconnect(void);
void usb_serial_transfer_complete(bool in, int status, int length);
void usb_serial_transfer_complete(int ep,bool in, int status, int length);
bool usb_serial_control_request(struct usb_ctrlrequest* req);
void usb_serial_send(unsigned char *data,int length);

View file

@ -326,23 +326,32 @@ void usb_storage_init(void)
}
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
int interface_number,int endpoint)
int usb_storage_set_first_endpoint(int endpoint)
{
usb_endpoint = endpoint;
return endpoint + 1;
}
int usb_storage_set_first_interface(int interface)
{
usb_interface = interface;
return interface + 1;
}
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size)
{
endpoint_descriptor.wMaxPacketSize=max_packet_size;
interface_descriptor.bInterfaceNumber=interface_number;
interface_descriptor.bInterfaceNumber=usb_interface;
memcpy(dest,&interface_descriptor,
sizeof(struct usb_interface_descriptor));
dest+=sizeof(struct usb_interface_descriptor);
endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN,
memcpy(dest,&endpoint_descriptor,
sizeof(struct usb_endpoint_descriptor));
dest+=sizeof(struct usb_endpoint_descriptor);
endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT,
memcpy(dest,&endpoint_descriptor,
sizeof(struct usb_endpoint_descriptor));
@ -350,11 +359,8 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
2*sizeof(struct usb_endpoint_descriptor);
}
void usb_storage_init_connection(int interface,int endpoint)
void usb_storage_init_connection(void)
{
usb_interface = interface;
usb_endpoint = endpoint;
logf("ums: set config");
/* prime rx endpoint. We only need room for commands */
state = WAITING_FOR_COMMAND;
@ -377,8 +383,9 @@ void usb_storage_init_connection(int interface,int endpoint)
}
/* called by usb_core_transfer_complete() */
void usb_storage_transfer_complete(bool in,int status,int length)
void usb_storage_transfer_complete(int ep,bool in,int status,int length)
{
(void)ep;
struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
//logf("transfer result %X %d", status, length);

View file

@ -21,11 +21,12 @@
#include "usb_ch9.h"
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
int interface_number,int endpoint);
void usb_storage_init_connection(int interface,int endpoint);
int usb_storage_set_first_endpoint(int endpoint);
int usb_storage_set_first_interface(int interface);
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size);
void usb_storage_init_connection(void);
void usb_storage_init(void);
void usb_storage_transfer_complete(bool in,int state,int length);
void usb_storage_transfer_complete(int ep,bool in,int state,int length);
bool usb_storage_control_request(struct usb_ctrlrequest* req);
#ifdef HAVE_HOTSWAP
void usb_storage_notify_hotswap(int volume,bool inserted);