1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-12-29 19:44:16 +02:00

further towards a usb file system

This commit is contained in:
Bas Wijnen 2010-01-14 22:04:19 +01:00
parent 0c1dfe719b
commit 03e74d38d3
3 changed files with 62 additions and 9 deletions

View File

@ -158,11 +158,19 @@ class Udc:
char log_buffer[1000] char log_buffer[1000]
unsigned log_buffer_size unsigned log_buffer_size
unsigned log_buffer_start unsigned log_buffer_start
Kernel::Cap caller
bool have_caller
public: public:
void init () void init ()
void log (unsigned c) void log (unsigned c)
void interrupt (unsigned cmd) void interrupt (unsigned cmd)
void send (unsigned code, unsigned arg) 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::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 = { 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_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_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' } } 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_size = 0
log_buffer_start = 0 log_buffer_start = 0
cmd_code = ~0 cmd_code = ~0
@ -229,9 +238,24 @@ bool Udc::vendor (Setup *s, unsigned cmd):
if !(s->request_type & 0x80): if !(s->request_type & 0x80):
switch s->request: switch s->request:
case Directory::GET_SIZE: 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: 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: default:
kdebug ("invalid vendor request\n") kdebug ("invalid vendor request\n")
Kernel::panic (0) Kernel::panic (0)
@ -369,6 +393,7 @@ void Udc::interrupt (unsigned cmd):
i = UDC_INTRIN i = UDC_INTRIN
if i & (1 << 0): if i & (1 << 0):
// Interrupt on endpoint 0. // Interrupt on endpoint 0.
UDC_INDEX = 0
unsigned csr = UDC_CSR0 unsigned csr = UDC_CSR0
if csr & UDC_CSR0_SENTSTALL: if csr & UDC_CSR0_SENTSTALL:
csr &= ~(UDC_CSR0_SENTSTALL | UDC_CSR0_SENDSTALL) csr &= ~(UDC_CSR0_SENTSTALL | UDC_CSR0_SENDSTALL)
@ -411,6 +436,18 @@ void Udc::interrupt (unsigned cmd):
state = IDLE state = IDLE
break break
UDC_CSR0 = csr 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): void Udc::log (unsigned c):
if log_buffer_size >= sizeof (log_buffer): if log_buffer_size >= sizeof (log_buffer):

View File

@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = usb-server bin_PROGRAMS = usb-server
usb_server_SOURCES = usb-server.cc 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 usb_server_LDFLAGS = $(SHEVEK_LIBS) -lusb
PYPP = /usr/bin/pypp PYPP = /usr/bin/pypp

View File

@ -26,6 +26,7 @@
#include <shevek/mainloop.hh> #include <shevek/mainloop.hh>
#include <shevek/server.hh> #include <shevek/server.hh>
#include <shevek/args.hh> #include <shevek/args.hh>
#include <shevek/dir.hh>
#include "devices.hh" #include "devices.hh"
struct client struct client
@ -69,6 +70,17 @@ struct data:
void get_device (unsigned vendor, unsigned product, unsigned tries) void get_device (unsigned vendor, unsigned product, unsigned tries)
void poll () 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 <Name> dir
static std::string files (".")
unsigned lock (0)
void data::poll (): void data::poll ():
while true: while true:
unsigned buffer[2] unsigned buffer[2]
@ -89,7 +101,7 @@ void data::poll ():
break break
case Directory::GET_SIZE: case Directory::GET_SIZE:
unsigned long long size = dir.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 std::cerr << "unable to send size to device: " << usb_strerror () << std::endl
usb_release_interface (handle, 0) usb_release_interface (handle, 0)
usb_close (handle) usb_close (handle)
@ -112,7 +124,10 @@ void data::poll ():
continue continue
case Directory::LOCK_RO: case Directory::LOCK_RO:
if !lock++: 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 continue
case Directory::UNLOCK_RO: case Directory::UNLOCK_RO:
if !lock: if !lock:
@ -121,7 +136,8 @@ void data::poll ():
usb_close (handle) usb_close (handle)
handle = NULL handle = NULL
return return
--lock if !--lock:
dir.clear ()
continue continue
case Directory::GET_FILE_RO: case Directory::GET_FILE_RO:
unsigned f = buffer[0] >> 16 unsigned f = buffer[0] >> 16
@ -131,13 +147,13 @@ void data::poll ():
usb_close (handle) usb_close (handle)
handle = NULL handle = NULL
return return
std::ifstream file (dir[f]) std::ifstream file (dir[f].full.c_str ())
file.seek (buffer[1] << 12) file.seekg (buffer[1] << 12)
char page[1 << 12] char page[1 << 12]
memset (page, 0, 1 << 12) memset (page, 0, 1 << 12)
file.read (page, 1 << 12) file.read (page, 1 << 12)
for unsigned i = 0; i < (1 << 12); i += 64: 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 std::cerr << "unable to send file to device: " << usb_strerror () << std::endl
usb_release_interface (handle, 0) usb_release_interface (handle, 0)
usb_close (handle) usb_close (handle)