- prepared USB flash stick implementation (patch by Ben Lunt - not yet complete)

This commit is contained in:
Volker Ruppert 2005-11-07 19:06:05 +00:00
parent 3f149870b0
commit 9934d3b46b
5 changed files with 283 additions and 16 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: config.cc,v 1.56 2005-11-06 16:48:49 vruppert Exp $
// $Id: config.cc,v 1.57 2005-11-07 19:06:05 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -1041,22 +1041,38 @@ void bx_init_options ()
"port #1 device",
"Device connected to USB port #1",
"", BX_PATHNAME_LEN);
bx_options.usb[i].Ooption1 = new bx_param_string_c (
BXP_USBx_OPTION1(i+1),
"port #1 device options",
"Options for device on USB port #1",
"", BX_PATHNAME_LEN);
bx_options.usb[i].Oport2 = new bx_param_string_c (
BXP_USBx_PORT2(i+1),
"port #2 device",
"Device connected to USB port #2",
"", BX_PATHNAME_LEN);
deplist = new bx_list_c (BXP_NULL, 2);
bx_options.usb[i].Ooption2 = new bx_param_string_c (
BXP_USBx_OPTION2(i+1),
"port #2 device options",
"Options for device on USB port #2",
"", BX_PATHNAME_LEN);
deplist = new bx_list_c (BXP_NULL, 4);
deplist->add (bx_options.usb[i].Oport1);
deplist->add (bx_options.usb[i].Ooption1);
deplist->add (bx_options.usb[i].Oport2);
deplist->add (bx_options.usb[i].Ooption2);
bx_options.usb[i].Oenabled->set_dependent_list (deplist);
// add to menu
*par_ser_ptr++ = bx_options.usb[i].Oenabled;
*par_ser_ptr++ = bx_options.usb[i].Oport1;
*par_ser_ptr++ = bx_options.usb[i].Ooption1;
*par_ser_ptr++ = bx_options.usb[i].Oport2;
*par_ser_ptr++ = bx_options.usb[i].Ooption2;
bx_options.usb[i].Oport1->set_group (strdup(group));
bx_options.usb[i].Ooption1->set_group (strdup(group));
bx_options.usb[i].Oport2->set_group (strdup(group));
bx_options.usb[i].Ooption2->set_group (strdup(group));
}
// add final NULL at the end, and build the menu
*par_ser_ptr = NULL;
@ -1791,7 +1807,9 @@ void bx_reset_options ()
for (i=0; i<BX_N_USB_HUBS; i++) {
bx_options.usb[i].Oenabled->reset();
bx_options.usb[i].Oport1->reset();
bx_options.usb[i].Ooption1->reset();
bx_options.usb[i].Oport2->reset();
bx_options.usb[i].Ooption2->reset();
}
// interface
@ -2898,8 +2916,12 @@ parse_line_formatted(char *context, int num_params, char *params[])
bx_options.usb[idx].Oenabled->set (atol(&params[i][8]));
} else if (!strncmp(params[i], "port1=", 6)) {
bx_options.usb[idx].Oport1->set (strdup(&params[i][6]));
} else if (!strncmp(params[i], "option1=", 6)) {
bx_options.usb[idx].Ooption1->set (strdup(&params[i][6]));
} else if (!strncmp(params[i], "port2=", 6)) {
bx_options.usb[idx].Oport2->set (strdup(&params[i][6]));
} else if (!strncmp(params[i], "option2=", 6)) {
bx_options.usb[idx].Ooption2->set (strdup(&params[i][6]));
} else if (!strncmp(params[i], "ioaddr=", 7)) {
PARSE_WARN(("%s: usb ioaddr is now deprecated (assigned by BIOS).", context));
} else if (!strncmp(params[i], "irq=", 4)) {
@ -3433,7 +3455,8 @@ bx_write_usb_options (FILE *fp, bx_usb_options *opt, int n)
{
fprintf (fp, "usb%d: enabled=%d", n, opt->Oenabled->get ());
if (opt->Oenabled->get ()) {
fprintf (fp, ", port1=%s, port2=%s", opt->Oport1->getptr (), opt->Oport2->getptr ());
fprintf (fp, ", port1=%s, option1=%s", opt->Oport1->getptr (), opt->Ooption1->getptr ());
fprintf (fp, ", port2=%s, option2=%s", opt->Oport2->getptr (), opt->Ooption2->getptr ());
}
fprintf (fp, "\n");
return 0;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.146 2005-10-28 13:49:24 vruppert Exp $
// $Id: siminterface.h,v 1.147 2005-11-07 19:06:05 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Intro to siminterface by Bryce Denney:
@ -340,10 +340,12 @@ typedef enum {
BXP_COM4_ENABLED,
BXP_COM4_MODE,
BXP_COM4_PATH,
#define BXP_PARAMS_PER_USB_HUB 3
#define BXP_PARAMS_PER_USB_HUB 5
BXP_USB1_ENABLED,
BXP_USB1_PORT1,
BXP_USB1_OPTION1,
BXP_USB1_PORT2,
BXP_USB1_OPTION2,
BXP_PRIVATE_COLORMAP,
BXP_FULLSCREEN,
BXP_SCREENMODE,
@ -522,8 +524,12 @@ typedef enum {
(bx_id)(BXP_USB1_ENABLED + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
#define BXP_USBx_PORT1(x) \
(bx_id)(BXP_USB1_PORT1 + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
#define BXP_USBx_OPTION1(x) \
(bx_id)(BXP_USB1_OPTION1 + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
#define BXP_USBx_PORT2(x) \
(bx_id)(BXP_USB1_PORT2 + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
#define BXP_USBx_OPTION2(x) \
(bx_id)(BXP_USB1_OPTION2 + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
// use x=1,2
#define BXP_PARPORTx_ENABLED(x) \
@ -1354,7 +1360,9 @@ typedef struct {
typedef struct {
bx_param_bool_c *Oenabled;
bx_param_string_c *Oport1;
bx_param_string_c *Ooption1;
bx_param_string_c *Oport2;
bx_param_string_c *Ooption2;
} bx_usb_options;
typedef struct {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pciusb.cc,v 1.25 2005-11-05 12:57:17 vruppert Exp $
// $Id: pciusb.cc,v 1.26 2005-11-07 19:06:05 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -212,10 +212,12 @@ bx_pciusb_c::reset(unsigned type)
for (i=0; i<BX_USB_CONFDEV; i++)
for (j=0; j<USB_CUR_DEVS; j++) {
memset(&BX_USB_THIS hub[i].device[j], 0, sizeof(USB_DEVICE));
BX_USB_THIS hub[i].device[j].fd = -1;
}
BX_USB_THIS keyboard_connected = 0;
BX_USB_THIS mouse_connected = 0;
BX_USB_THIS flash_connected = 0;
// include the device(s) initialize code
#include "pciusb_devs.h"
@ -245,6 +247,10 @@ bx_pciusb_c::init_device(Bit8u port, char *devname)
type = USB_DEV_TYPE_KEYPAD;
connected = 1;
BX_USB_THIS keyboard_connected = 1;
//} else if (!strcmp(devname, "flash")) {
// type = USB_DEV_TYPE_FLASH;
// connected = 1;
// BX_USB_THIS flash_connected = 1;
} else {
BX_PANIC(("unknown USB device: %s", devname));
return;
@ -586,7 +592,7 @@ void bx_pciusb_c::usb_timer(void)
// *** This assumes that we can complete the frame within the 1ms time allowed ***
// Actually, not complete, but reach the end of the frame. This means that there may still
// be TDs and QHs that were BREADTH defined and will be executed on the next cycle/iteration.
// *** Does Bochs interrupt this timer, or does it wait for the return before it fires the next timer????
if (BX_USB_THIS busy) {
@ -594,6 +600,7 @@ void bx_pciusb_c::usb_timer(void)
BX_USB_THIS busy = 0;
}
if (BX_USB_THIS hub[0].usb_command.schedule) {
struct USB_DEVICE *dev = NULL;
BX_USB_THIS busy = 1;
bx_bool fire_int = 0;
set_irq_level(0); // make sure it is low
@ -655,7 +662,7 @@ void bx_pciusb_c::usb_timer(void)
// issue short packet?
Bit16u r_actlen = (((td.dword1 & 0x7FF)+1) & 0x7FF);
Bit16u r_maxlen = (((td.dword2>>21)+1) & 0x7FF);
BX_INFO((" r_actlen = 0x%04X r_maxlen = 0x%04X", r_actlen, r_maxlen));
BX_DEBUG((" r_actlen = 0x%04X r_maxlen = 0x%04X", r_actlen, r_maxlen));
if (((td.dword2 & 0xFF) == TOKEN_IN) && spd && stk && (r_actlen < r_maxlen) && ((td.dword1 & 0x00FF0000) == 0)) {
shortpacket = 1;
td.dword1 |= (1<<29);
@ -681,7 +688,7 @@ void bx_pciusb_c::usb_timer(void)
} else {
if (stack[stk].t) break;
}
}
}
@ -718,7 +725,7 @@ void bx_pciusb_c::usb_timer(void)
BX_USB_THIS busy = 0; // ready to do next frame item
} // end run schedule
// if host turned off the schedule, set the halted bit in the status register
// Note: Can not use an else from the if() above since the host can changed this bit
// while we are processing a frame.
@ -821,7 +828,7 @@ bx_bool bx_pciusb_c::DoTransfer(Bit32u address, Bit32u queue_num, struct TD *td)
cnt = dev->function.device_config[dev->config].Interface[dev->Interface].endpts[0].max_size;
switch (protocol) {
case 1: // keypad
memcpy(device_buffer, BX_USB_THIS key_pad_packet, 8);
BX_MEM_WRITE_PHYSICAL(td->dword3, cnt, device_buffer);
@ -845,6 +852,15 @@ bx_bool bx_pciusb_c::DoTransfer(Bit32u address, Bit32u queue_num, struct TD *td)
BX_USB_THIS set_status(td, 0, 0, 0, 0, 0, 0, cnt-1);
break;
case 0x50: // USB Mass Storage ????
Bit8u bulk_int_packet[1024];
if (flash_stick(bulk_int_packet, maxlen, 0)) {
} else {
}
break;
default:
BX_PANIC(("Unknown/unsupported endpt protocol issued an Interrupt In / Bulk packet. protocol %i", protocol));
}
@ -915,6 +931,14 @@ bx_bool bx_pciusb_c::DoTransfer(Bit32u address, Bit32u queue_num, struct TD *td)
BX_PANIC(("Mouse received and OUT packet!"));
break;
case 0x50: // USB Mass Storage ????
if (flash_stick(bulk_int_packet, maxlen, 1)) {
} else {
}
break;
default:
BX_PANIC(("Unknown/unsupported endpt protocol issued an Interrupt Out / Bulk packet. protocol %i", protocol));
}
@ -1072,7 +1096,7 @@ bx_bool bx_pciusb_c::DoTransfer(Bit32u address, Bit32u queue_num, struct TD *td)
(td->dword1 & 0x20000000)?1:0, (td->dword1 & 0x18000000)>>27, (td->dword1 & 0x04000000)?1:0, (td->dword1 & 0x02000000)?1:0, (td->dword1 & 0x01000000)?1:0, (td->dword1 & 0x00FF0000)>>16, td->dword1 & 0x000007FF,
(td->dword2 & 0xFFE00000)>>21, (td->dword2 & 0x00080000)?1:0, (td->dword2 & 0x00078000)>>15, (td->dword2 & 0x00007F00)>>8, td->dword2 & 0x000000FF,
td->dword3));
switch (dev->state) {
case STATE_DEFAULT:
case STATE_ADDRESS:
@ -1222,6 +1246,17 @@ bx_bool bx_pciusb_c::DoTransfer(Bit32u address, Bit32u queue_num, struct TD *td)
BX_USB_THIS set_status(td, 0, 0, 0, 0, 0, 0, 0x007); // an 8 byte packet was received
}
break;
case 0xFE:
// The Kingston driver sends the control packet.
// At the moment, I haven't a clue to what it is.
// are we ready.???
dev->scratch = 0;
dev->function.in = (Bit8u *) &dev->scratch;
dev->function.in_cnt = 1;
BX_USB_THIS set_status(td, 1, 0, 0, 0, (pid==TOKEN_SETUP)?1:0, 0, 0x007); // an 8 byte packet was received, but stalled
break;
default:
BX_PANIC((" **** illegal or unknown REQUEST sent to Host Controller: %02x", data[1]));
}
@ -1567,11 +1602,31 @@ bx_pciusb_c::usb_set_connect_status(Bit8u port, int type, bx_bool connected)
if (BX_USB_THIS hub[0].usb_command.suspend) {
BX_USB_THIS hub[0].usb_port[port].resume = 1;
BX_USB_THIS hub[0].usb_status.resume = 1;
if( BX_USB_THIS hub[0].usb_enable.resume) {
if (BX_USB_THIS hub[0].usb_enable.resume) {
BX_USB_THIS hub[0].usb_status.interrupt = 1;
set_irq_level(1);
}
}
// If the type is a flash stick, we need to close, then re open the file connected with it.
// **** We current assume the flash stick is on port1 ****
/*
if (type == USB_DEV_TYPE_FLASH) {
if (BX_USB_THIS hub[0].device[BX_USB_THIS hub[0].usb_port[port].device_num].fd > -1)
::close(BX_USB_THIS hub[0].device[BX_USB_THIS hub[0].usb_port[port].device_num].fd);
BX_USB_THIS hub[0].device[BX_USB_THIS hub[0].usb_port[port].device_num].fd =
::open(bx_options.usb[0].Opath1->getptr(), O_RDWR | O_BINARY);
if (BX_USB_THIS hub[0].device[BX_USB_THIS hub[0].usb_port[port].device_num].fd < 0)
BX_PANIC(("Could not open file for USB flash stick: %s", bx_options.usb[0].Opath1->getptr()));
// look at size of image file to calculate disk geometry
struct stat stat_buf;
int ret = fstat(BX_USB_THIS hub[0].device[BX_USB_THIS hub[0].usb_port[port].device_num].fd, &stat_buf);
if (ret) BX_PANIC(("fstat() returns error!"));
if (stat_buf.st_size != (USB_FLASH_SIZE * 0x00100000))
BX_PANIC(("size of disk image must be %i Megs", USB_FLASH_SIZE));
}
*/
} else {
BX_USB_THIS hub[0].usb_port[port].status = 0;
BX_USB_THIS hub[0].usb_port[port].connect_changed = 1;
@ -1738,4 +1793,34 @@ bx_pciusb_c::dump_packet(Bit8u *data, unsigned size) {
BX_DEBUG(("%s", the_packet));
}
// usb flash stick support
// packet is the data coming in/going out
// size is the size of the data
// out = 1 if Host to Device, 0 it Device to Host
bx_bool
bx_pciusb_c::flash_stick(Bit8u *packet, Bit16u size, bx_bool out) {
// packet contains the SCSI interface command
dump_packet(packet, size);
if (out) {
// TODO:
// From this point on, it is simply a SCSI command interface.
// We could set up the image so that we could use the existing
// harddrv.cc and cdrom.cc code and our flash.img file.
// At this point, I don't have the time to do this, but if someone
// else would like to, please do.
} else {
// For now, I will not implement the write part.
}
return 1;
}
#endif // BX_SUPPORT_PCI && BX_SUPPORT_PCIUSB

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pciusb.h,v 1.12 2005-11-05 12:57:18 vruppert Exp $
// $Id: pciusb.h,v 1.13 2005-11-07 19:06:05 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -38,7 +38,7 @@
#define BX_USB_CONFDEV 1 /* only 1 USB hub currently */
#define USB_NUM_PORTS 2 /* UHCI supports 2 ports per root hub */
#define USB_CUR_DEVS 2
#define USB_CUR_DEVS 3
#define TOKEN_IN 0x69
#define TOKEN_OUT 0xE1
@ -82,6 +82,7 @@ struct KEYPAD {
#define USB_DEV_TYPE_NONE 0
#define USB_DEV_TYPE_MOUSE 1
#define USB_DEV_TYPE_KEYPAD 2
#define USB_DEV_TYPE_FLASH 3
// set it to 1 (align on byte) and save so we can pop it
#pragma pack(push, 1)
@ -95,6 +96,8 @@ struct USB_DEVICE {
Bit8u endpt; // which endpt to use
unsigned state; // the state the device is in. DEFAULT, ADDRESS, or CONFIGURED
bx_bool low_speed; // 1 = ls
Bit32u scratch; // 32-bit scratch area
int fd; // if this device accesses a file, this is the handle.
bx_bool in_stall; // is this device in a stall state?
Bit8u stall_once; // some devices stall on the first setup packet after powerup
struct {
@ -370,6 +373,7 @@ private:
bx_bool last_connect;
bx_bool keyboard_connected;
bx_bool mouse_connected;
bx_bool flash_connected;
static void init_device(Bit8u port, char *devname);
static void usb_set_connect_status(Bit8u port, int type, bx_bool connected);
@ -378,6 +382,7 @@ private:
void usb_timer(void);
bx_bool DoTransfer(Bit32u address, Bit32u queue_num, struct TD *);
void dump_packet(Bit8u *data, unsigned size);
bx_bool flash_stick(Bit8u *packet, Bit16u size, bx_bool out);
unsigned GetDescriptor(struct USB_DEVICE *, struct REQUEST_PACKET *);
void set_status(struct TD *td, bx_bool stalled, bx_bool data_buffer_error, bx_bool babble,
bx_bool nak, bx_bool crc_time_out, bx_bool bitstuff_error, Bit16u act_len);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pciusb_devs.h,v 1.5 2005-11-05 12:57:18 vruppert Exp $
// $Id: pciusb_devs.h,v 1.6 2005-11-07 19:06:05 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -36,6 +36,7 @@
// defines
#define USB_CYPRESS 1
#define USB_KEYPAD 1
#define USB_FLASH_STICK 1
// don't forget to modify USB_CUR_DEVS to reflect devices
@ -385,6 +386,151 @@
#endif // USB_KEYPAD
///////////////////////////////////////////////////////////////////////////////////////////////
// Kingston USB 256meg flash stick.
// WinXP supports this stick
// Win98SE needs a driver found at www.kingston.com/drivers/dt198
#if USB_FLASH_STICK
#define USB_FLASH_SIZE 256
BX_USB_THIS hub[0].device[2].connect_status = 0;
BX_USB_THIS hub[0].device[2].dev_type = USB_DEV_TYPE_FLASH;
BX_USB_THIS hub[0].device[2].state = STATE_DEFAULT;
BX_USB_THIS hub[0].device[2].address = 0;
BX_USB_THIS hub[0].device[2].alt_interface = 0;
BX_USB_THIS hub[0].device[2].Interface = 0;
BX_USB_THIS hub[0].device[2].config = 0;
BX_USB_THIS hub[0].device[2].endpt = 1;
BX_USB_THIS hub[0].device[2].function.direction = 0;
BX_USB_THIS hub[0].device[2].function.configs = 1; // only one config in this device
BX_USB_THIS hub[0].device[2].low_speed = 0;
BX_USB_THIS hub[0].device[2].in_stall = 0;
BX_USB_THIS hub[0].device[2].stall_once = 0x00; // stall on the first setup packet (set bit 0)
// device descriptor
BX_USB_THIS hub[0].device[2].function.device_descr.len = 18;
BX_USB_THIS hub[0].device[2].function.device_descr.type = DEVICE;
BX_USB_THIS hub[0].device[2].function.device_descr.usb_ver = 0x0200;
BX_USB_THIS hub[0].device[2].function.device_descr._class = 0;
BX_USB_THIS hub[0].device[2].function.device_descr.subclass = 0;
BX_USB_THIS hub[0].device[2].function.device_descr.protocol = 0;
BX_USB_THIS hub[0].device[2].function.device_descr.max_packet_size = 64;
BX_USB_THIS hub[0].device[2].function.device_descr.vendorid = 0x0930;
BX_USB_THIS hub[0].device[2].function.device_descr.productid = 0x6532;
BX_USB_THIS hub[0].device[2].function.device_descr.device_rel = 0x0100;
BX_USB_THIS hub[0].device[2].function.device_descr.manuf_indx = 0;
BX_USB_THIS hub[0].device[2].function.device_descr.prod_indx = 2;
BX_USB_THIS hub[0].device[2].function.device_descr.serial_indx = 3;
BX_USB_THIS hub[0].device[2].function.device_descr.configs = 1;
// config descriptor
BX_USB_THIS hub[0].device[2].function.device_config[0].len = 9;
BX_USB_THIS hub[0].device[2].function.device_config[0].type = CONFIG;
BX_USB_THIS hub[0].device[2].function.device_config[0].tot_len = 39; // size of config+interface+endpt+hid
BX_USB_THIS hub[0].device[2].function.device_config[0].interfaces = 1;
BX_USB_THIS hub[0].device[2].function.device_config[0].config_val = 1;
BX_USB_THIS hub[0].device[2].function.device_config[0].config_indx = 0;
BX_USB_THIS hub[0].device[2].function.device_config[0].attrbs = 0x80; //
BX_USB_THIS hub[0].device[2].function.device_config[0].max_power = 100;
// interface descriptor
// 0x09, 0x04, 0x00, 0x00, 0x03, 0x08, 0x06, 0x50, 0x00, // interface descriptor
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].size = 9;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].type = INTERFACE;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].interface_num = 0;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].alternate = 0;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].num_endpts = 3;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].iclass = 8;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].subclass = 6;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].protocol = 0x50;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].str_indx = 0;
// endpoint descriptor
// 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, // endpoint descriptor
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[0].size = 7;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[0].type = ENDPOINT;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[0].endpt = 0x81;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[0].attrib = 2;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[0].max_size = 64;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[0].interval = 0x00;
// endpoint descriptor
// 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, // endpoint descriptor
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[1].size = 7;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[1].type = ENDPOINT;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[1].endpt = 0x02;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[1].attrib = 2;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[1].max_size = 64;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[1].interval = 0x00;
// endpoint descriptor
// 0x07, 0x05, 0x83, 0x03, 0x40, 0x00, 0x01, // endpoint descriptor
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[2].size = 7;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[2].type = ENDPOINT;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[2].endpt = 0x83;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[2].attrib = 3;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[2].max_size = 64;
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].endpts[2].interval = 0x01;
// string descriptors
BX_USB_THIS hub[0].device[2].function.str_descriptor.size = 0x04;
BX_USB_THIS hub[0].device[2].function.str_descriptor.type = 0x03;
BX_USB_THIS hub[0].device[2].function.str_descriptor.langid[0] = 0x0409;
// string #1
BX_USB_THIS hub[0].device[2].function.string[0].size = 36;
BX_USB_THIS hub[0].device[2].function.string[0].type = 3;
Bit8u dev3_str_1[64] = { 'U', 0x00, 'S', 0x00, 'B', 0x00, ' ', 0x00, 'F', 0x00, 'l', 0x00, 'a', 0x00,
's', 0x00, 'h', 0x00, ' ', 0x00, 'S', 0x00, 't', 0x00, 'i', 0x00, 'c', 0x00, 'k', 0x00, '.', 0x00,
'0', 0x00,
};
memcpy(BX_USB_THIS hub[0].device[2].function.string[0].unicode_str, dev3_str_1, 34);
// string #2
BX_USB_THIS hub[0].device[2].function.string[1].size = 36;
BX_USB_THIS hub[0].device[2].function.string[1].type = 3;
Bit8u dev3_str_2[64] = { 'U', 0x00, 'S', 0x00, 'B', 0x00, ' ', 0x00, 'F', 0x00, 'l', 0x00, 'a', 0x00,
's', 0x00, 'h', 0x00, ' ', 0x00, 'S', 0x00, 't', 0x00, 'i', 0x00, 'c', 0x00, 'k', 0x00, '.', 0x00,
'1', 0x00,
};
memcpy(BX_USB_THIS hub[0].device[2].function.string[1].unicode_str, dev3_str_2, 34);
// string #3
BX_USB_THIS hub[0].device[2].function.string[2].size = 36;
BX_USB_THIS hub[0].device[2].function.string[2].type = 3;
Bit8u dev3_str_3[64] = { 'U', 0x00, 'S', 0x00, 'B', 0x00, ' ', 0x00, 'F', 0x00, 'l', 0x00, 'a', 0x00,
's', 0x00, 'h', 0x00, ' ', 0x00, 'S', 0x00, 't', 0x00, 'i', 0x00, 'c', 0x00, 'k', 0x00, '.', 0x00,
'2', 0x00,
};
memcpy(BX_USB_THIS hub[0].device[2].function.string[2].unicode_str, dev3_str_3, 34);
// string #4
BX_USB_THIS hub[0].device[2].function.string[3].size = 36;
BX_USB_THIS hub[0].device[2].function.string[3].type = 3;
Bit8u dev3_str_4[64] = { 'U', 0x00, 'S', 0x00, 'B', 0x00, ' ', 0x00, 'F', 0x00, 'l', 0x00, 'a', 0x00,
's', 0x00, 'h', 0x00, ' ', 0x00, 'S', 0x00, 't', 0x00, 'i', 0x00, 'c', 0x00, 'k', 0x00, '.', 0x00,
'3', 0x00,
};
memcpy(BX_USB_THIS hub[0].device[2].function.string[3].unicode_str, dev3_str_4, 34);
// string #5
BX_USB_THIS hub[0].device[2].function.string[4].size = 36;
BX_USB_THIS hub[0].device[2].function.string[4].type = 3;
Bit8u dev3_str_5[64] = { 'U', 0x00, 'S', 0x00, 'B', 0x00, ' ', 0x00, 'F', 0x00, 'l', 0x00, 'a', 0x00,
's', 0x00, 'h', 0x00, ' ', 0x00, 'S', 0x00, 't', 0x00, 'i', 0x00, 'c', 0x00, 'k', 0x00, '.', 0x00,
'4', 0x00,
};
memcpy(BX_USB_THIS hub[0].device[2].function.string[3].unicode_str, dev3_str_5, 34);
// this device has no key conversion table
BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].lookup_cnt = 0;
memset(&BX_USB_THIS hub[0].device[2].function.device_config[0].Interface[0].lookup, 0, sizeof(struct KEYPAD) * KEYPAD_LEN);
#endif // USB_FLASH_STICK
// Another device would go here.