diff --git a/boot-programs/udc.ccp b/boot-programs/udc.ccp index 95d9daa..167d458 100644 --- a/boot-programs/udc.ccp +++ b/boot-programs/udc.ccp @@ -158,11 +158,19 @@ class Udc: char log_buffer[1000] unsigned log_buffer_size unsigned log_buffer_start + Kernel::Cap caller + bool have_caller public: void init () void log (unsigned c) void interrupt (unsigned cmd) void send (unsigned code, unsigned arg) + void set_caller (Kernel::Cap c): + if have_caller: + kdebug ("set_caller double-called\n") + Kernel::panic (0) + caller = c + have_caller = true Udc::Device Udc::device_descriptor = { sizeof (Device), Device::Type, 0x200, 0, 0, 0, max_packet_size0, 0xfffe, 0x0002, 0x100, 1, 2, 0, 1 } Udc::my_config Udc::config_descriptor = { @@ -198,6 +206,7 @@ void Udc::init (): s_langs = (String <1>){ sizeof (String <1>), String <1>::Type, { 0x0409 } } s_manufacturer = (String <6>){ sizeof (String <6>), String <6>::Type, { 's', 'h', 'e', 'v', 'e', 'k' } } s_product = (String <16>){ sizeof (String <16>), String <16>::Type, { 'I', 'r', 'i', 's', ' ', 'o', 'n', ' ', 'N', 'a', 'n', 'o', 'N', 'o', 't', 'e' } } + have_caller = false log_buffer_size = 0 log_buffer_start = 0 cmd_code = ~0 @@ -229,9 +238,24 @@ bool Udc::vendor (Setup *s, unsigned cmd): if !(s->request_type & 0x80): switch s->request: case Directory::GET_SIZE: - //TODO + if !have_caller: + kdebug ("received size from server without a caller waiting\n") + Kernel::panic (0) + unsigned size_l = UDC_FIFO (0) + unsigned size_h = UDC_FIFO (0) + caller.invoke (Kernel::Num (size_l, size_h)) + have_caller = false + break case Directory::GET_NAME: - //TODO + if !have_caller: + kdebug ("received size from server without a caller waiting\n") + Kernel::panic (0) + unsigned n[4] + for unsigned i = 0; i < 4; ++i: + n[i] = UDC_FIFO (0) + caller.invoke (Kernel::Num (n[0], n[1]), Kernel::Num (n[2], n[3])) + have_caller = false + break default: kdebug ("invalid vendor request\n") Kernel::panic (0) @@ -369,6 +393,7 @@ void Udc::interrupt (unsigned cmd): i = UDC_INTRIN if i & (1 << 0): // Interrupt on endpoint 0. + UDC_INDEX = 0 unsigned csr = UDC_CSR0 if csr & UDC_CSR0_SENTSTALL: csr &= ~(UDC_CSR0_SENTSTALL | UDC_CSR0_SENDSTALL) @@ -411,6 +436,18 @@ void Udc::interrupt (unsigned cmd): state = IDLE break UDC_CSR0 = csr + unsigned i = UDC_INTROUT + if i & (1 << 1): + // Interrupt on OUT endpoint 1. + UDC_INDEX = 1 + unsigned csr = UDC_OUTCSR + if !csr & UDC_CSR_OUTPKTRDY: + kdebug ("unrecognized interrupt on bulk out ep 1\n") + return + for unsigned i = 0; i < 16; ++i: + *p++ = UDC_FIFO (1) + if p - page == PAGE_SIZE: + // TODO: notify caller; reset buffer. void Udc::log (unsigned c): if log_buffer_size >= sizeof (log_buffer): diff --git a/mips/nanonote/server/Makefile.am b/mips/nanonote/server/Makefile.am index 735585b..284160b 100644 --- a/mips/nanonote/server/Makefile.am +++ b/mips/nanonote/server/Makefile.am @@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = usb-server usb_server_SOURCES = usb-server.cc -usb_server_CPPFLAGS = $(SHEVEK_CFLAGS) -DSTAGE1_FILE=\"mips/nanonote/sdram-setup.raw\" -DSTAGE2_FILE=\"iris.raw\" +usb_server_CPPFLAGS = $(SHEVEK_CFLAGS) -DSTAGE1_FILE=\"mips/nanonote/sdram-setup.raw\" -DSTAGE2_FILE=\"iris.raw\" -I../../.. usb_server_LDFLAGS = $(SHEVEK_LIBS) -lusb PYPP = /usr/bin/pypp diff --git a/mips/nanonote/server/usb-server.ccp b/mips/nanonote/server/usb-server.ccp index 5f7aedd..ab7e97a 100644 --- a/mips/nanonote/server/usb-server.ccp +++ b/mips/nanonote/server/usb-server.ccp @@ -26,6 +26,7 @@ #include #include #include +#include #include "devices.hh" struct client @@ -69,6 +70,17 @@ struct data: void get_device (unsigned vendor, unsigned product, unsigned tries) void poll () +struct Name: + char name[16] + std::string full + Name (std::string const &n): + full = n + memset (name, 0, 16) + memcpy (name, n.data (), n.size () > 16 ? 16 : n.size ()) +static std::vector dir +static std::string files (".") +unsigned lock (0) + void data::poll (): while true: unsigned buffer[2] @@ -89,7 +101,7 @@ void data::poll (): break case Directory::GET_SIZE: unsigned long long size = dir.size () - if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, Directory::GET_SIZE, 0, 0, (char const *)&size, 8, timeout) != 8: + if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, Directory::GET_SIZE, 0, 0, (char *)&size, 8, timeout) != 8: std::cerr << "unable to send size to device: " << usb_strerror () << std::endl usb_release_interface (handle, 0) usb_close (handle) @@ -112,7 +124,10 @@ void data::poll (): continue case Directory::LOCK_RO: if !lock++: - dir.load (files) + shevek::dir d (files) + dir.clear () + for shevek::dir::const_iterator i = d.begin (); i == d.end (); ++i: + dir.push_back (Name (i->name)) continue case Directory::UNLOCK_RO: if !lock: @@ -121,7 +136,8 @@ void data::poll (): usb_close (handle) handle = NULL return - --lock + if !--lock: + dir.clear () continue case Directory::GET_FILE_RO: unsigned f = buffer[0] >> 16 @@ -131,13 +147,13 @@ void data::poll (): usb_close (handle) handle = NULL return - std::ifstream file (dir[f]) - file.seek (buffer[1] << 12) + std::ifstream file (dir[f].full.c_str ()) + file.seekg (buffer[1] << 12) char page[1 << 12] memset (page, 0, 1 << 12) file.read (page, 1 << 12) for unsigned i = 0; i < (1 << 12); i += 64: - if usb_bulk_write (handle, 1 | USB_ENDPOINT_OUT, p, 64) != 64: + if usb_bulk_write (handle, 1 | USB_ENDPOINT_OUT, &page[i], 64, timeout) != 64: std::cerr << "unable to send file to device: " << usb_strerror () << std::endl usb_release_interface (handle, 0) usb_close (handle)