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:
parent
33c44461e1
commit
bec6aa3176
10 changed files with 279 additions and 152 deletions
|
@ -235,6 +235,7 @@ drivers/audio/mas35xx.c
|
||||||
usbstack/usb_core.c
|
usbstack/usb_core.c
|
||||||
usbstack/usb_storage.c
|
usbstack/usb_storage.c
|
||||||
usbstack/usb_serial.c
|
usbstack/usb_serial.c
|
||||||
|
usbstack/usb_charging_only.c
|
||||||
#if CONFIG_USBOTG == USBOTG_ARC
|
#if CONFIG_USBOTG == USBOTG_ARC
|
||||||
target/arm/usb-drv-arc.c
|
target/arm/usb-drv-arc.c
|
||||||
#elif CONFIG_USBOTG == USBOTG_ISP1583
|
#elif CONFIG_USBOTG == USBOTG_ISP1583
|
||||||
|
|
|
@ -53,6 +53,7 @@ void usb_core_enable_driver(int driver,bool enabled);
|
||||||
bool usb_core_driver_enabled (int driver);
|
bool usb_core_driver_enabled (int driver);
|
||||||
void usb_core_handle_transfer_completion(
|
void usb_core_handle_transfer_completion(
|
||||||
struct usb_transfer_completion_event_data* event);
|
struct usb_transfer_completion_event_data* event);
|
||||||
|
int usb_core_ack_control(struct usb_ctrlrequest* req);
|
||||||
#ifdef HAVE_HOTSWAP
|
#ifdef HAVE_HOTSWAP
|
||||||
void usb_core_hotswap_event(int volume,bool inserted);
|
void usb_core_hotswap_event(int volume,bool inserted);
|
||||||
#endif
|
#endif
|
||||||
|
|
72
firmware/usbstack/usb_charging_only.c
Normal file
72
firmware/usbstack/usb_charging_only.c
Normal 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*/
|
31
firmware/usbstack/usb_charging_only.h
Normal file
31
firmware/usbstack/usb_charging_only.h
Normal 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
|
||||||
|
|
|
@ -23,41 +23,65 @@
|
||||||
/* Common api, implemented by all class drivers */
|
/* Common api, implemented by all class drivers */
|
||||||
|
|
||||||
struct usb_class_driver {
|
struct usb_class_driver {
|
||||||
|
/* First some runtime data */
|
||||||
bool enabled;
|
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;
|
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
|
/* Asks the driver to put the interface descriptor and all other
|
||||||
needed descriptor for this driver at dest, for the given settings.
|
needed descriptor for this driver at dest.
|
||||||
Returns the number of bytes taken by these descriptors. */
|
Returns the number of bytes taken by these descriptors.
|
||||||
int (*get_config_descriptor)(unsigned char *dest,
|
Mandatory function */
|
||||||
int max_packet_size, int interface_number, int endpoint);
|
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
|
/* Tells the driver that a usb connection has been set up and is now
|
||||||
ready to use. */
|
ready to use.
|
||||||
void (*init_connection)(int interface,int endpoint);
|
Optional function */
|
||||||
|
void (*init_connection)(void);
|
||||||
|
|
||||||
/* Initialises the driver. This can be called multiple times,
|
/* Initialises the driver. This can be called multiple times,
|
||||||
and should not perform any action that can disturb other threads
|
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);
|
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);
|
void (*disconnect)(void);
|
||||||
|
|
||||||
/* Tells the driver that a usb transfer has been completed. Note that "in"
|
/* Tells the driver that a usb transfer has been completed. Note that "in"
|
||||||
is relative to the host */
|
is relative to the host
|
||||||
void (*transfer_complete)(bool in, int status, int length);
|
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
|
/* 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
|
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);
|
bool (*control_request)(struct usb_ctrlrequest* req);
|
||||||
|
|
||||||
#ifdef HAVE_HOTSWAP
|
#ifdef HAVE_HOTSWAP
|
||||||
/* Tells the driver that a hotswappable disk/card was inserted or
|
/* Tells the driver that a hotswappable disk/card was inserted or
|
||||||
extracted */
|
extracted
|
||||||
|
Optional function */
|
||||||
void (*notify_hotswap)(int volume, bool inserted);
|
void (*notify_hotswap)(int volume, bool inserted);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
#include "usb_serial.h"
|
#include "usb_serial.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USB_CHARGING_ONLY)
|
||||||
|
#include "usb_charging_only.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: Move target-specific stuff somewhere else (serial number reading) */
|
/* TODO: Move target-specific stuff somewhere else (serial number reading) */
|
||||||
|
|
||||||
#ifdef HAVE_AS3514
|
#ifdef HAVE_AS3514
|
||||||
|
@ -91,22 +95,6 @@ static struct usb_config_descriptor __attribute__((aligned(2)))
|
||||||
.bMaxPower = 250, /* 500mA in 2mA units */
|
.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)))
|
static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
|
||||||
qualifier_descriptor =
|
qualifier_descriptor =
|
||||||
|
@ -160,21 +148,12 @@ static const struct usb_string_descriptor __attribute__((aligned(2)))
|
||||||
{0x0409} /* LANGID US English */
|
{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[] =
|
static const struct usb_string_descriptor* const usb_strings[] =
|
||||||
{
|
{
|
||||||
&lang_descriptor,
|
&lang_descriptor,
|
||||||
&usb_string_iManufacturer,
|
&usb_string_iManufacturer,
|
||||||
&usb_string_iProduct,
|
&usb_string_iProduct,
|
||||||
&usb_string_iSerial,
|
&usb_string_iSerial
|
||||||
&usb_string_charging_only
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int usb_address = 0;
|
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_core_num_interfaces;
|
||||||
|
|
||||||
static int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
|
static struct
|
||||||
int interface_number,int endpoint);
|
{
|
||||||
|
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] =
|
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] = {
|
[USB_DRIVER_MASS_STORAGE] = {
|
||||||
.enabled = false,
|
.enabled = false,
|
||||||
.needs_exclusive_ata = true,
|
.needs_exclusive_ata = true,
|
||||||
.usb_endpoint = 0,
|
.first_interface = 0,
|
||||||
.usb_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,
|
.get_config_descriptor = usb_storage_get_config_descriptor,
|
||||||
.init_connection = usb_storage_init_connection,
|
.init_connection = usb_storage_init_connection,
|
||||||
.init = usb_storage_init,
|
.init = usb_storage_init,
|
||||||
|
@ -209,8 +194,10 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
[USB_DRIVER_SERIAL] = {
|
[USB_DRIVER_SERIAL] = {
|
||||||
.enabled = false,
|
.enabled = false,
|
||||||
.needs_exclusive_ata = false,
|
.needs_exclusive_ata = false,
|
||||||
.usb_endpoint = 0,
|
.first_interface = 0,
|
||||||
.usb_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,
|
.get_config_descriptor = usb_serial_get_config_descriptor,
|
||||||
.init_connection = usb_serial_init_connection,
|
.init_connection = usb_serial_init_connection,
|
||||||
.init = usb_serial_init,
|
.init = usb_serial_init,
|
||||||
|
@ -226,9 +213,11 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
[USB_DRIVER_CHARGING_ONLY] = {
|
[USB_DRIVER_CHARGING_ONLY] = {
|
||||||
.enabled = false,
|
.enabled = false,
|
||||||
.needs_exclusive_ata = false,
|
.needs_exclusive_ata = false,
|
||||||
.usb_endpoint = 0,
|
.first_interface = 0,
|
||||||
.usb_interface = 0,
|
.last_interface = 0,
|
||||||
.get_config_descriptor = usb_charging_get_config_descriptor,
|
.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_connection = NULL,
|
||||||
.init = NULL,
|
.init = NULL,
|
||||||
.disconnect = 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 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 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',
|
static short hex[16] = {'0','1','2','3','4','5','6','7',
|
||||||
'8','9','A','B','C','D','E','F'};
|
'8','9','A','B','C','D','E','F'};
|
||||||
|
@ -331,17 +318,6 @@ void usb_core_init(void)
|
||||||
logf("usb_core_init() finished");
|
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)
|
void usb_core_exit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -360,27 +336,20 @@ void usb_core_exit(void)
|
||||||
void usb_core_handle_transfer_completion(
|
void usb_core_handle_transfer_completion(
|
||||||
struct usb_transfer_completion_event_data* event)
|
struct usb_transfer_completion_event_data* event)
|
||||||
{
|
{
|
||||||
int i;
|
int ep = event->endpoint;
|
||||||
switch(event->endpoint) {
|
switch(ep) {
|
||||||
case EP_CONTROL:
|
case EP_CONTROL:
|
||||||
logf("ctrl handled %ld",current_tick);
|
logf("ctrl handled %ld",current_tick);
|
||||||
usb_core_control_request_handler(
|
usb_core_control_request_handler(
|
||||||
(struct usb_ctrlrequest*)event->data);
|
(struct usb_ctrlrequest*)event->data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for(i=0;i<USB_NUM_DRIVERS;i++) {
|
if(ep_data[ep].completion_handler != NULL)
|
||||||
if(drivers[i].enabled &&
|
ep_data[ep].completion_handler(ep,event->in,
|
||||||
drivers[i].usb_endpoint == event->endpoint &&
|
|
||||||
drivers[i].transfer_complete != NULL)
|
|
||||||
{
|
|
||||||
drivers[i].transfer_complete(event->in,
|
|
||||||
event->status,event->length);
|
event->status,event->length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void usb_core_enable_driver(int driver,bool enabled)
|
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)
|
static void allocate_interfaces_and_endpoints(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i,j;
|
||||||
int interface=0;
|
int interface=0;
|
||||||
int endpoint=1;
|
int endpoint=1;
|
||||||
|
|
||||||
|
memset(ep_data,0,sizeof(ep_data));
|
||||||
|
|
||||||
for(i=0;i<USB_NUM_DRIVERS;i++) {
|
for(i=0;i<USB_NUM_DRIVERS;i++) {
|
||||||
if(drivers[i].enabled) {
|
if(drivers[i].enabled) {
|
||||||
drivers[i].usb_endpoint = endpoint++;
|
int oldendpoint = endpoint;
|
||||||
drivers[i].usb_interface = interface++;
|
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) {
|
if(endpoint>NUM_ENDPOINTS) {
|
||||||
drivers[i].enabled = false;
|
drivers[i].enabled = false;
|
||||||
|
@ -463,7 +448,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
response_data[0] = 1;
|
response_data[0] = 1;
|
||||||
if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
|
if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
|
||||||
break;
|
break;
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
case USB_REQ_SET_CONFIGURATION:
|
case USB_REQ_SET_CONFIGURATION:
|
||||||
logf("usb_core: SET_CONFIG");
|
logf("usb_core: SET_CONFIG");
|
||||||
|
@ -474,22 +459,20 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
if(drivers[i].enabled &&
|
if(drivers[i].enabled &&
|
||||||
drivers[i].init_connection!=NULL)
|
drivers[i].init_connection!=NULL)
|
||||||
{
|
{
|
||||||
drivers[i].init_connection(
|
drivers[i].init_connection();
|
||||||
drivers[i].usb_interface,
|
|
||||||
drivers[i].usb_endpoint);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
usb_state = ADDRESS;
|
usb_state = ADDRESS;
|
||||||
}
|
}
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_REQ_SET_ADDRESS: {
|
case USB_REQ_SET_ADDRESS: {
|
||||||
unsigned char address = req->wValue;
|
unsigned char address = req->wValue;
|
||||||
logf("usb_core: SET_ADR %d", address);
|
logf("usb_core: SET_ADR %d", address);
|
||||||
if(ack_control(req)!=0)
|
if(usb_core_ack_control(req)!=0)
|
||||||
break;
|
break;
|
||||||
usb_drv_cancel_all_transfers();
|
usb_drv_cancel_all_transfers();
|
||||||
usb_address = address;
|
usb_address = address;
|
||||||
|
@ -537,9 +520,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
{
|
{
|
||||||
size+=drivers[i].get_config_descriptor(
|
size+=drivers[i].get_config_descriptor(
|
||||||
&response_data[size],
|
&response_data[size],
|
||||||
max_packet_size,
|
max_packet_size);
|
||||||
drivers[i].usb_interface,
|
|
||||||
drivers[i].usb_endpoint);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config_descriptor.bNumInterfaces =
|
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)
|
if(usb_drv_send(EP_CONTROL, response_data, length)!=0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
} /* USB_REQ_GET_DESCRIPTOR */
|
} /* USB_REQ_GET_DESCRIPTOR */
|
||||||
case USB_REQ_CLEAR_FEATURE:
|
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:
|
case USB_REQ_SET_FEATURE:
|
||||||
if(req->wValue == 2) { /* TEST_MODE */
|
if(req->wValue == 2) { /* TEST_MODE */
|
||||||
int mode=req->wIndex>>8;
|
int mode=req->wIndex>>8;
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
usb_drv_set_test_mode(mode);
|
usb_drv_set_test_mode(mode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -604,7 +585,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
response_data[1]= 0;
|
response_data[1]= 0;
|
||||||
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
|
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
|
||||||
break;
|
break;
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -614,7 +595,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
switch (req->bRequest) {
|
switch (req->bRequest) {
|
||||||
case USB_REQ_SET_INTERFACE:
|
case USB_REQ_SET_INTERFACE:
|
||||||
logf("usb_core: SET_INTERFACE");
|
logf("usb_core: SET_INTERFACE");
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_REQ_GET_INTERFACE:
|
case USB_REQ_GET_INTERFACE:
|
||||||
|
@ -622,7 +603,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
response_data[0] = 0;
|
response_data[0] = 0;
|
||||||
if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
|
if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
|
||||||
break;
|
break;
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
case USB_REQ_CLEAR_FEATURE:
|
case USB_REQ_CLEAR_FEATURE:
|
||||||
break;
|
break;
|
||||||
|
@ -633,14 +614,15 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
response_data[1]= 0;
|
response_data[1]= 0;
|
||||||
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
|
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
|
||||||
break;
|
break;
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
bool handled=false;
|
bool handled=false;
|
||||||
for(i=0;i<USB_NUM_DRIVERS;i++) {
|
for(i=0;i<USB_NUM_DRIVERS;i++) {
|
||||||
if(drivers[i].enabled &&
|
if(drivers[i].enabled &&
|
||||||
drivers[i].control_request &&
|
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);
|
handled = drivers[i].control_request(req);
|
||||||
}
|
}
|
||||||
|
@ -649,7 +631,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
/* nope. flag error */
|
/* nope. flag error */
|
||||||
logf("usb bad req %d", req->bRequest);
|
logf("usb bad req %d", req->bRequest);
|
||||||
usb_drv_stall(EP_CONTROL, true,true);
|
usb_drv_stall(EP_CONTROL, true,true);
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -661,13 +643,13 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
if (req->wValue == 0 ) /* ENDPOINT_HALT */
|
if (req->wValue == 0 ) /* ENDPOINT_HALT */
|
||||||
usb_drv_stall(req->wIndex & 0xf, false,
|
usb_drv_stall(req->wIndex & 0xf, false,
|
||||||
(req->wIndex & 0x80) !=0);
|
(req->wIndex & 0x80) !=0);
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
case USB_REQ_SET_FEATURE:
|
case USB_REQ_SET_FEATURE:
|
||||||
if (req->wValue == 0 ) /* ENDPOINT_HALT */
|
if (req->wValue == 0 ) /* ENDPOINT_HALT */
|
||||||
usb_drv_stall(req->wIndex & 0xf, true,
|
usb_drv_stall(req->wIndex & 0xf, true,
|
||||||
(req->wIndex & 0x80) !=0);
|
(req->wIndex & 0x80) !=0);
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
case USB_REQ_GET_STATUS:
|
case USB_REQ_GET_STATUS:
|
||||||
response_data[0]= 0;
|
response_data[0]= 0;
|
||||||
|
@ -678,23 +660,17 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
(req->wIndex&0x80)!=0);
|
(req->wIndex&0x80)!=0);
|
||||||
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
|
if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
|
||||||
break;
|
break;
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
bool handled=false;
|
bool handled=false;
|
||||||
for(i=0;i<USB_NUM_DRIVERS;i++) {
|
if(ep_data[req->wIndex & 0xf].control_handler != NULL)
|
||||||
if(drivers[i].enabled &&
|
handled = ep_data[req->wIndex & 0xf].control_handler(req);
|
||||||
drivers[i].control_request &&
|
|
||||||
drivers[i].usb_endpoint == (req->wIndex & 0xf))
|
|
||||||
{
|
|
||||||
handled = drivers[i].control_request(req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!handled) {
|
if(!handled) {
|
||||||
/* nope. flag error */
|
/* nope. flag error */
|
||||||
logf("usb bad req %d", req->bRequest);
|
logf("usb bad req %d", req->bRequest);
|
||||||
usb_drv_stall(EP_CONTROL, true,true);
|
usb_drv_stall(EP_CONTROL, true,true);
|
||||||
ack_control(req);
|
usb_core_ack_control(req);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -719,13 +695,13 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
events[endpoint].endpoint=endpoint;
|
ep_data[endpoint].completion_event.endpoint=endpoint;
|
||||||
events[endpoint].in=in;
|
ep_data[endpoint].completion_event.in=in;
|
||||||
events[endpoint].data=0;
|
ep_data[endpoint].completion_event.data=0;
|
||||||
events[endpoint].status=status;
|
ep_data[endpoint].completion_event.status=status;
|
||||||
events[endpoint].length=length;
|
ep_data[endpoint].completion_event.length=length;
|
||||||
/* All other endoints. Let the thread deal with it */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -733,16 +709,16 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
|
||||||
/* called by usb_drv_int() */
|
/* called by usb_drv_int() */
|
||||||
void usb_core_control_request(struct usb_ctrlrequest* req)
|
void usb_core_control_request(struct usb_ctrlrequest* req)
|
||||||
{
|
{
|
||||||
events[0].endpoint=0;
|
ep_data[0].completion_event.endpoint=0;
|
||||||
events[0].in=0;
|
ep_data[0].completion_event.in=0;
|
||||||
events[0].data=(void *)req;
|
ep_data[0].completion_event.data=(void *)req;
|
||||||
events[0].status=0;
|
ep_data[0].completion_event.status=0;
|
||||||
events[0].length=0;
|
ep_data[0].completion_event.length=0;
|
||||||
logf("ctrl received %ld",current_tick);
|
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)
|
if (req->bRequestType & 0x80)
|
||||||
return usb_drv_recv(EP_CONTROL, NULL, 0);
|
return usb_drv_recv(EP_CONTROL, NULL, 0);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#ifdef USB_SERIAL
|
#ifdef USB_SERIAL
|
||||||
|
|
||||||
/* serial interface */
|
/* serial interface */
|
||||||
struct usb_interface_descriptor __attribute__((aligned(2)))
|
static struct usb_interface_descriptor __attribute__((aligned(2)))
|
||||||
interface_descriptor =
|
interface_descriptor =
|
||||||
{
|
{
|
||||||
.bLength = sizeof(struct usb_interface_descriptor),
|
.bLength = sizeof(struct usb_interface_descriptor),
|
||||||
|
@ -42,7 +42,8 @@ struct usb_interface_descriptor __attribute__((aligned(2)))
|
||||||
.iInterface = 0
|
.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),
|
.bLength = sizeof(struct usb_endpoint_descriptor),
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
@ -90,31 +91,42 @@ static void sendout(void)
|
||||||
busy_sending=true;
|
busy_sending=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
|
int usb_serial_set_first_endpoint(int endpoint)
|
||||||
int interface_number,int endpoint)
|
|
||||||
{
|
{
|
||||||
endpoint_descriptor.wMaxPacketSize=max_packet_size;
|
usb_endpoint = endpoint;
|
||||||
interface_descriptor.bInterfaceNumber=interface_number;
|
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));
|
memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
|
||||||
dest+=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));
|
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
|
||||||
dest+=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));
|
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
|
||||||
return sizeof(struct usb_interface_descriptor) +
|
dest+=sizeof(struct usb_endpoint_descriptor);
|
||||||
2 * 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 */
|
/* prime rx endpoint */
|
||||||
usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer);
|
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() */
|
/* 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) {
|
switch (in) {
|
||||||
case false:
|
case false:
|
||||||
logf("serial: %s", receive_buffer);
|
logf("serial: %s", receive_buffer);
|
||||||
|
|
|
@ -21,12 +21,13 @@
|
||||||
|
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
|
|
||||||
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
|
int usb_serial_set_first_endpoint(int endpoint);
|
||||||
int interface_number, int endpoint);
|
int usb_serial_set_first_interface(int interface);
|
||||||
void usb_serial_init_connection(int interface,int endpoint);
|
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_init(void);
|
||||||
void usb_serial_disconnect(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);
|
bool usb_serial_control_request(struct usb_ctrlrequest* req);
|
||||||
|
|
||||||
void usb_serial_send(unsigned char *data,int length);
|
void usb_serial_send(unsigned char *data,int length);
|
||||||
|
|
|
@ -326,23 +326,32 @@ void usb_storage_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
|
int usb_storage_set_first_endpoint(int endpoint)
|
||||||
int interface_number,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;
|
endpoint_descriptor.wMaxPacketSize=max_packet_size;
|
||||||
interface_descriptor.bInterfaceNumber=interface_number;
|
interface_descriptor.bInterfaceNumber=usb_interface;
|
||||||
|
|
||||||
|
|
||||||
memcpy(dest,&interface_descriptor,
|
memcpy(dest,&interface_descriptor,
|
||||||
sizeof(struct usb_interface_descriptor));
|
sizeof(struct usb_interface_descriptor));
|
||||||
dest+=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,
|
memcpy(dest,&endpoint_descriptor,
|
||||||
sizeof(struct usb_endpoint_descriptor));
|
sizeof(struct usb_endpoint_descriptor));
|
||||||
dest+=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,
|
memcpy(dest,&endpoint_descriptor,
|
||||||
sizeof(struct usb_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);
|
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");
|
logf("ums: set config");
|
||||||
/* prime rx endpoint. We only need room for commands */
|
/* prime rx endpoint. We only need room for commands */
|
||||||
state = WAITING_FOR_COMMAND;
|
state = WAITING_FOR_COMMAND;
|
||||||
|
@ -377,8 +383,9 @@ void usb_storage_init_connection(int interface,int endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called by usb_core_transfer_complete() */
|
/* 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;
|
struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
|
||||||
|
|
||||||
//logf("transfer result %X %d", status, length);
|
//logf("transfer result %X %d", status, length);
|
||||||
|
|
|
@ -21,11 +21,12 @@
|
||||||
|
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
|
|
||||||
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
|
int usb_storage_set_first_endpoint(int endpoint);
|
||||||
int interface_number,int endpoint);
|
int usb_storage_set_first_interface(int interface);
|
||||||
void usb_storage_init_connection(int interface,int endpoint);
|
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_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);
|
bool usb_storage_control_request(struct usb_ctrlrequest* req);
|
||||||
#ifdef HAVE_HOTSWAP
|
#ifdef HAVE_HOTSWAP
|
||||||
void usb_storage_notify_hotswap(int volume,bool inserted);
|
void usb_storage_notify_hotswap(int volume,bool inserted);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue