[Endpoint-commits] rev 2 - in trunk: . librbc libsbp2 src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Jul 7 11:38:42 CDT 2003


Author: manish
Date: 2003-07-07 05:38:37 -0500 (Mon, 07 Jul 2003)
New Revision: 2

Added:
   trunk/AUTHORS
   trunk/COPYING
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/NEWS
   trunk/README
   trunk/autogen.sh
   trunk/configure.in
   trunk/librbc/
   trunk/librbc/Makefile.am
   trunk/librbc/rbcbuffer.h
   trunk/librbc/rbccommand.c
   trunk/librbc/rbccommand.h
   trunk/librbc/rbcdisk.h
   trunk/librbc/rbcmanage.c
   trunk/librbc/rbcmanage.h
   trunk/librbc/rbcprivate.h
   trunk/libsbp2/
   trunk/libsbp2/Makefile.am
   trunk/libsbp2/sbp2byteswap.h
   trunk/libsbp2/sbp2configrom.c
   trunk/libsbp2/sbp2configrom.h
   trunk/libsbp2/sbp2constants.h
   trunk/libsbp2/sbp2csr.h
   trunk/libsbp2/sbp2login.h
   trunk/libsbp2/sbp2logout.h
   trunk/libsbp2/sbp2main.c
   trunk/libsbp2/sbp2main.h
   trunk/libsbp2/sbp2manager.c
   trunk/libsbp2/sbp2manager.h
   trunk/libsbp2/sbp2pagetable.h
   trunk/libsbp2/sbp2pointer.h
   trunk/libsbp2/sbp2querylogins.h
   trunk/libsbp2/sbp2raw1394.c
   trunk/libsbp2/sbp2raw1394.h
   trunk/libsbp2/sbp2reconnect.h
   trunk/libsbp2/sbp2scsicommand.h
   trunk/libsbp2/sbp2scsistatus.h
   trunk/libsbp2/sbp2status.h
   trunk/libsbp2/sbp2worker.c
   trunk/libsbp2/sbp2worker.h
   trunk/src/
   trunk/src/Makefile.am
   trunk/src/main.c
Log:
Sync

Added: trunk/AUTHORS
==============================================================================
--- trunk/AUTHORS	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/AUTHORS	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1 @@
+Manish Singh <manish.singh at oracle.com>

Added: trunk/COPYING
==============================================================================
--- trunk/COPYING	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/COPYING	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

Added: trunk/ChangeLog
==============================================================================

Added: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/Makefile.am	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1 @@
+SUBDIRS = librbc libsbp2 src

Added: trunk/NEWS
==============================================================================

Added: trunk/README
==============================================================================
--- trunk/README	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/README	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,4 @@
+Endpoint turns a Linux machine with one or more firewire cards into an SBP-2
+device. The advantage is that you can use any file or device the linux
+machine supports as storage, and that multiple clients can sit on separate
+buses so they can get the full bandwidth of the bus.

Added: trunk/autogen.sh
==============================================================================
--- trunk/autogen.sh	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/autogen.sh	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+aclocal $ACLOCAL_FLAGS
+libtoolize --copy --force
+autoheader
+automake -a
+autoconf
+
+./configure --enable-maintainer-mode "$@"

Added: trunk/configure.in
==============================================================================
--- trunk/configure.in	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/configure.in	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,50 @@
+AC_PREREQ(2.53)
+
+AC_INIT(libsbp2/sbp2manager.c)
+
+PACKAGE=endpoint
+
+ENDPOINT_MAJOR_VERSION=0
+ENDPOINT_MINOR_VERSION=1
+ENDPOINT_MICRO_VERSION=0
+
+VERSION=$ENDPOINT_MAJOR.VERSION.$ENDPOINT_MINOR_VERSION.$ENDPOINT_MICRO_VERSION
+
+AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
+
+AM_CONFIG_HEADER(config.h)
+
+AM_MAINTAINER_MODE
+
+ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
+
+AC_PROG_CC
+AM_PROG_LIBTOOL
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_CPP
+
+if eval "test x$GCC = xyes"; then
+  case " $CFLAGS " in
+  *[\ \	]-Wall[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wall" ;;
+  esac
+fi
+
+dnl AC_LIB_RAW1394(0.9.0,,
+dnl   AC_MSG_ERROR([Could not find libraw1394]))
+
+PKG_CHECK_MODULES(GLIB, glib-2.0,,
+  AC_MSG_ERROR([Could not find GLIB 2.x]))
+
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+AC_OUTPUT([
+Makefile
+librbc/Makefile
+libsbp2/Makefile
+src/Makefile
+])

Added: trunk/librbc/Makefile.am
==============================================================================
--- trunk/librbc/Makefile.am	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/Makefile.am	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,18 @@
+lib_LTLIBRARIES = libendpointrbc.la
+
+INCLUDES = \
+	-I$(top_srcdir)	\
+	$(GLIB_CFLAGS)	\
+	-I$(includedir)
+
+libendpointrbc_la_SOURCES = \
+	rbcbuffer.h	\
+	rbccommand.h	\
+	rbccommand.c	\
+	rbcdisk.h	\
+	rbcmanage.c	\
+	rbcmanage.h	\
+	rbcprivate.h
+
+libendpointrbc_la_LIBADD = \
+	$(GLIB_LIBS)

Added: trunk/librbc/rbcbuffer.h
==============================================================================
--- trunk/librbc/rbcbuffer.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbcbuffer.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,57 @@
+/*
+ * Endpoint - Linux SBP2 Disk Target
+ *
+ * Copyright (C) 2003 Oracle.  All rights reserved.
+ *
+ * Author: Manish Singh <manish.singh at oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have recieved a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef __RBC_BUFFER_H__
+#define __RBC_BUFFER_H__
+
+
+#include <glib.h>
+
+
+typedef enum
+{
+  RBC_BUFFER_TYPE_EMPTY,
+  RBC_BUFFER_TYPE_SIMPLE,
+  RBC_BUFFER_TYPE_PAGE
+} RBCBufferType;
+
+
+typedef struct _RBCBuffer RBCBuffer;
+typedef struct _RBCPage   RBCPage;
+
+struct _RBCBuffer
+{
+  RBCBufferType type;
+
+  gpointer      data;
+  gsize         length;
+};
+
+struct _RBCPage
+{
+  gpointer data;
+  gsize    length;
+};
+
+
+#endif /* __RBC_BUFFER_H__ */

Added: trunk/librbc/rbccommand.c
==============================================================================
--- trunk/librbc/rbccommand.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbccommand.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,291 @@
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
+
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+#include <glib.h>
+
+#include "rbccommand.h"
+#include "rbcprivate.h"
+
+
+#define VENDOR_ID   "Linux   "
+#define PRODUCT_ID  "Endpoint        "
+#define PRODUCT_REV "0001"
+
+
+enum
+{
+  CMD_INQUIRY         = 0x12,
+  CMD_MODE_SELECT     = 0x15,
+  CMD_MODE_SENSE      = 0x1a,
+  CMD_READ            = 0x28,
+  CMD_READ_CAPACITY   = 0x25,
+  CMD_START_STOP_UNIT = 0x1b,
+  CMD_TEST_UNIT_READY = 0x00,
+  CMD_VERIFY          = 0x2f,
+  CMD_WRITE           = 0x2a,
+  CMD_WRITE_BUFFER    = 0x3b
+};
+
+
+typedef gboolean (*CommandHandler) (RBCDisk   *disk,
+				    guint8    *cmd,
+				    RBCBuffer *buffer,
+				    guint8    *sense);
+
+
+static gboolean handle_inquiry         (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_mode_select     (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_mode_sense      (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_read            (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_read_capacity   (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_start_stop_unit (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_test_unit_ready (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_verify          (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_write           (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+static gboolean handle_write_buffer    (RBCDisk   *disk,
+					guint8    *cmd,
+					RBCBuffer *buffer,
+					guint8    *sense);
+
+
+gboolean
+rbc_disk_command (RBCDisk   *disk,
+		  guint8    *cmd,
+		  RBCBuffer *buffer,
+		  guint8    *sense)
+{
+  CommandHandler handler;
+
+  switch (cmd[0])
+    {
+    case CMD_INQUIRY:
+      handler = handle_inquiry;
+      break;
+
+    case CMD_MODE_SELECT:
+      handler = handle_mode_select;
+      break;
+
+    case CMD_MODE_SENSE:
+      handler = handle_mode_sense;
+      break;
+
+    case CMD_READ:
+      handler = handle_read;
+      break;
+
+    case CMD_READ_CAPACITY:
+      handler = handle_read_capacity;
+      break;
+
+    case CMD_START_STOP_UNIT:
+      handler = handle_start_stop_unit;
+      break;
+
+    case CMD_TEST_UNIT_READY:
+      handler = handle_test_unit_ready;
+      break;
+   
+    case CMD_VERIFY:
+      handler = handle_verify; 
+      break;
+
+    case CMD_WRITE:
+      handler = handle_write;
+      break;
+
+    case CMD_WRITE_BUFFER:
+      handler = handle_write_buffer;
+      break;
+
+    default:
+      return FALSE;
+      break;
+    }
+
+  return handler (disk, cmd, buffer, sense);
+}
+
+static gboolean
+handle_inquiry (RBCDisk   *disk,
+		guint8    *cmd,
+		RBCBuffer *buffer,
+		guint8    *sense)
+{
+  guint8 *data = buffer->data;
+
+  memset (data, 0, buffer->length);
+
+  data[0] = 0xe;
+
+  memcpy (&data[8],  VENDOR_ID,   8);
+  memcpy (&data[16], PRODUCT_ID,  16);
+  memcpy (&data[32], PRODUCT_REV, 4);
+
+  return TRUE;
+}
+
+static gboolean
+handle_mode_select (RBCDisk   *disk,
+		    guint8    *cmd,
+		    RBCBuffer *buffer,
+		    guint8    *sense)
+{
+  return FALSE;
+}
+
+static gboolean
+handle_mode_sense (RBCDisk   *disk,
+		   guint8    *cmd,
+		   RBCBuffer *buffer,
+		   guint8    *sense)
+{
+  return FALSE;
+}
+
+static gboolean
+handle_read (RBCDisk   *disk,
+	     guint8    *cmd,
+	     RBCBuffer *buffer,
+	     guint8    *sense)
+{
+  gsize block;
+  gsize num;
+  off_t offset;
+  gsize length;
+
+  block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
+  num = cmd[8] + (cmd[7] << 8);
+
+  if (block + num > disk->capacity)
+    return FALSE;
+
+  offset = (off_t) block * RBC_BLOCK_SIZE;
+  length = num * RBC_BLOCK_SIZE;
+
+  if (buffer->type == RBC_BUFFER_TYPE_PAGE)
+    {
+      lseek (disk->fd, offset, SEEK_SET);
+      readv (disk->fd, buffer->data, buffer->length);
+    }
+  else if (buffer->type == RBC_BUFFER_TYPE_SIMPLE)
+    pread (disk->fd, buffer->data, offset, length);
+
+  return TRUE;
+}
+
+static gboolean
+handle_read_capacity (RBCDisk   *disk,
+		      guint8    *cmd,
+		      RBCBuffer *buffer,
+		      guint8    *sense)
+{
+  guint8 *data = buffer->data;
+  gsize capacity = disk->capacity;
+
+  memset (data, 0, buffer->length);
+
+  data[0] = (capacity >> 24);
+  data[1] = (capacity >> 16) & 0xff;
+  data[2] = (capacity >> 8) & 0xff;
+  data[3] = capacity & 0xff;
+  data[6] = (RBC_BLOCK_SIZE >> 8) & 0xff;
+  data[7] = RBC_BLOCK_SIZE & 0xff;
+
+  return TRUE;
+}
+
+static gboolean
+handle_start_stop_unit (RBCDisk   *disk,
+			guint8    *cmd,
+			RBCBuffer *buffer,
+			guint8    *sense)
+{
+  /* Power condition requests are unsupported, ignore */
+  return TRUE;
+}
+
+static gboolean
+handle_test_unit_ready (RBCDisk   *disk,
+			guint8    *cmd,
+			RBCBuffer *buffer,
+			guint8    *sense)
+{
+  /* We're always ready */
+  return TRUE;
+}
+
+static gboolean
+handle_verify (RBCDisk   *disk,
+	       guint8    *cmd,
+	       RBCBuffer *buffer,
+	       guint8    *sense)
+{
+  return FALSE;
+}
+
+static gboolean
+handle_write (RBCDisk   *disk,
+	      guint8    *cmd,
+	      RBCBuffer *buffer,
+	      guint8    *sense)
+{
+  gsize block;
+  gsize num;
+
+  block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
+  num = cmd[8] + (cmd[7] << 8);
+
+  if (block + num > disk->capacity)
+    return FALSE;
+
+  if (buffer->type == RBC_BUFFER_TYPE_SIMPLE)
+    pwrite (disk->fd, buffer->data, num * RBC_BLOCK_SIZE,
+	    (off_t) block * RBC_BLOCK_SIZE);
+  else
+    return FALSE;
+    
+  return TRUE;
+}
+
+static gboolean 
+handle_write_buffer (RBCDisk   *disk,
+		     guint8    *cmd,
+		     RBCBuffer *buffer,
+		     guint8    *sense)
+{
+  /* Unsupported, always succeed */
+  return TRUE;
+}

Added: trunk/librbc/rbccommand.h
==============================================================================
--- trunk/librbc/rbccommand.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbccommand.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,17 @@
+#ifndef __RBC_COMMAND_H__
+#define __RBC_COMMAND_H__
+
+
+#include <glib.h>
+
+#include <librbc/rbcbuffer.h>
+#include <librbc/rbcdisk.h>
+
+
+gboolean rbc_disk_command (RBCDisk   *disk,
+                           guint8    *cmd,
+			   RBCBuffer *buffer,
+			   guint8    *sense);
+
+
+#endif /* __RBC_COMMAND_H__ */

Added: trunk/librbc/rbcdisk.h
==============================================================================
--- trunk/librbc/rbcdisk.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbcdisk.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,8 @@
+#ifndef __RBC_DISK_H__
+#define __RBC_DISK_H__
+
+
+typedef struct _RBCDisk RBCDisk;
+
+
+#endif /* __RBC_DISK_H__ */

Added: trunk/librbc/rbcmanage.c
==============================================================================
--- trunk/librbc/rbcmanage.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbcmanage.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,45 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "rbcmanage.h"
+#include "rbcprivate.h"
+
+
+RBCDisk *
+rbc_disk_new (void)
+{
+  RBCDisk *disk;
+
+  disk = g_new (RBCDisk, 1);
+
+  disk->fd = open ("/root/diskimage", O_RDWR);
+  disk->capacity = 163840;
+
+  return disk;
+}
+
+void
+rbc_disk_destroy (RBCDisk *disk)
+{
+  close (disk->fd);
+
+  g_free (disk);
+}
+
+gboolean
+rbc_register_partition (RBCDisk     *disk,
+                        const gchar *filename,
+			gint         num)
+{
+  return TRUE;
+}
+
+gsize
+rbc_get_capacity (RBCDisk *disk)
+{
+  return disk->capacity;
+}

Added: trunk/librbc/rbcmanage.h
==============================================================================
--- trunk/librbc/rbcmanage.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbcmanage.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,21 @@
+#ifndef __RBC_MANAGE_H__
+#define __RBC_MANAGE_H__
+
+
+#include <glib.h>
+
+#include <librbc/rbcdisk.h>
+
+
+RBCDisk  *rbc_disk_new                (void);
+
+void      rbc_disk_destroy            (RBCDisk     *disk);
+
+gboolean  rbc_disk_register_partition (RBCDisk     *disk,
+                                       const gchar *filename,
+				       gint         num);
+
+gsize     rbc_disk_get_capacity       (RBCDisk     *disk);
+
+
+#endif /* __RBC_MANAGE_H__ */

Added: trunk/librbc/rbcprivate.h
==============================================================================
--- trunk/librbc/rbcprivate.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/librbc/rbcprivate.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,30 @@
+#ifndef __RBC_PRIVATE_H__
+#define __RBC_PRIVATE_H__
+
+
+#include <glib.h>
+
+#include <librbc/rbcdisk.h>
+
+
+#define RBC_BLOCK_SIZE 512
+
+
+typedef struct _RBCPartition RBCPartition;
+
+struct _RBCPartition
+{
+  gchar   *filename;
+  gint     fd;
+  gsize    size;
+};
+
+struct _RBCDisk
+{
+  GArray *partitions;
+  gsize   capacity;
+  gint    fd;
+};
+
+
+#endif /* __RBC_PRIVATE_H__ */

Added: trunk/libsbp2/Makefile.am
==============================================================================
--- trunk/libsbp2/Makefile.am	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/Makefile.am	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,31 @@
+lib_LTLIBRARIES = libendpointsbp2.la
+
+INCLUDES = \
+	-I$(top_srcdir)	\
+	$(GLIB_CFLAGS)	\
+	-I$(includedir)
+
+libendpointsbp2_la_SOURCES = \
+	sbp2byteswap.h		\
+	sbp2configrom.c		\
+	sbp2configrom.h		\
+	sbp2constants.h		\
+	sbp2csr.h		\
+	sbp2manager.c		\
+	sbp2manager.h		\
+	sbp2main.c		\
+	sbp2main.h		\
+	sbp2login.h		\
+	sbp2logout.h		\
+	sbp2pointer.h		\
+	sbp2querylogins.h	\
+	sbp2raw1394.c		\
+	sbp2raw1394.h		\
+	sbp2reconnect.h		\
+	sbp2status.h		\
+	sbp2worker.c		\
+	sbp2worker.h
+
+libendpointsbp2_la_LIBADD = \
+	$(top_builddir)/librbc/libendpointrbc.la	\
+	$(GLIB_LIBS)

Added: trunk/libsbp2/sbp2byteswap.h
==============================================================================
--- trunk/libsbp2/sbp2byteswap.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2byteswap.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,51 @@
+/*
+ * Endpoint - Linux SBP2 Disk Target
+ *
+ * Copyright (C) 2003 Oracle.  All rights reserved.
+ *
+ * Author: Manish Singh <manish.singh at oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have recieved a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef __SBP2_UTIL_H__
+#define __SBP2_UTIL_H__
+
+
+#include <glib.h>
+
+
+static inline void
+sbp2_byteswap_buffer (gpointer buffer,
+                      gint     length)
+{
+  guint32 *temp = buffer;
+
+  for (length = (length >> 2); length--; )
+    temp[length] = GUINT32_FROM_BE (temp[length]);
+}
+
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define sbp2_be32_to_cpu_buffer(b, l) sbp2_byteswap_buffer((b), (l))
+#define sbp2_cpu_to_be32_buffer(b, l) sbp2_byteswap_buffer((b), (l))
+#else /* G_BIG_ENDIAN */
+#define sbp2_be32_to_cpu_buffer(b, l) G_STMT_START { } G_STMT_END
+#define sbp2_cpu_to_be32_buffer(b, l) G_STMT_START { } G_STMT_END
+#endif
+
+
+#endif /* __SBP2_UTIL_H__ */

Added: trunk/libsbp2/sbp2configrom.c
==============================================================================
--- trunk/libsbp2/sbp2configrom.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2configrom.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,86 @@
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include "sbp2configrom.h"
+#include "sbp2csr.h"
+
+
+#define ROM_BUF_SIZE 256
+
+
+static guint16
+crc16 (guint32 *buf,
+       gint     length)
+{
+  gint    shift;
+  guint32 crc, sum, data;
+
+  crc = 0;
+
+  for (; length > 0; length--)
+    {
+      data = GUINT32_FROM_BE (*buf);
+
+      for (shift = 28; shift >= 0; shift -= 4)
+	{
+	  sum = ((crc >> 12) ^ (data >> shift)) & 0x000f;
+	  crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum;
+	}
+
+      crc &= 0xffff;
+
+      buf++;
+    }
+
+  return crc;
+}
+
+
+gboolean
+sbp2_setup_config_rom (raw1394handle_t handle)
+{
+  quadlet_t rom[ROM_BUF_SIZE];
+  gsize     rom_size;
+  guchar    rom_version;
+  gint      ret, i;
+
+  ret = raw1394_get_config_rom (handle, rom, ROM_BUF_SIZE,
+                                &rom_size, &rom_version);
+
+  if (ret != 0)
+    return FALSE;
+
+  if (rom[9] == GUINT32_FROM_BE(0xd1000008))
+    return TRUE;
+
+  for (i = 15; i > 8; i--)
+    rom[i + 1] = rom[i];
+
+  rom[7] = GUINT32_FROM_BE(0x81000003);
+  rom[9] = GUINT32_FROM_BE(0xd1000008);
+
+  rom[5] = GUINT32_FROM_BE(4 << 16 | crc16 (&rom[6], 4));
+
+  rom[18] = GUINT32_FROM_BE(0x1200609e);
+  rom[19] = GUINT32_FROM_BE(0x13010483);
+  rom[20] = GUINT32_FROM_BE(0x3800609e); /* IEEE/RAC */
+  rom[21] = GUINT32_FROM_BE(0x390104d8); /* IEEE/RAC */
+  rom[22] = GUINT32_FROM_BE(0x3b000000); /* IEEE/RAC */
+  rom[23] = GUINT32_FROM_BE(0x3c000001); /* IEEE/RAC */
+  rom[24] = GUINT32_FROM_BE(0x54000000 + SBP2_CSR_MANANGEMENT_OFFSET);
+  rom[25] = GUINT32_FROM_BE(0x3a003c08); /* unit characteristics */
+  rom[26] = GUINT32_FROM_BE(0x3d000003); /* reconnect timeout */
+  rom[27] = GUINT32_FROM_BE(0x144e0000); /* logical unit number */
+
+  rom[17] = GUINT32_FROM_BE(10 << 16 | crc16 (&rom[18], 10));
+
+  rom_size += 12 * 4;
+
+  ret = raw1394_update_config_rom (handle, rom, rom_size, rom_version);
+
+  if (ret == -1)
+    return FALSE;
+
+  return TRUE;
+}

Added: trunk/libsbp2/sbp2configrom.h
==============================================================================
--- trunk/libsbp2/sbp2configrom.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2configrom.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,11 @@
+#ifndef __SBP2_CONFIGROM_H__
+#define __SBP2_CONFIGROM_H__
+
+
+#include <libraw1394/raw1394.h>
+
+
+gboolean sbp2_setup_config_rom (raw1394handle_t handle);
+
+
+#endif /* __SBP2_CONFIGROM_H__ */

Added: trunk/libsbp2/sbp2constants.h
==============================================================================
--- trunk/libsbp2/sbp2constants.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2constants.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,8 @@
+#ifndef __SBP2_CONSTANTS_H__
+#define __SBP2_CONSTANTS_H__
+
+
+#define SBP2_RECONNECT_HOLD 3
+
+
+#endif /* __SBP2_CONSTANTS_H__ */

Added: trunk/libsbp2/sbp2csr.h
==============================================================================
--- trunk/libsbp2/sbp2csr.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2csr.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,13 @@
+#ifndef __SBP2_CSR_H__
+#define __SBP2_CSR_H__
+
+
+#define SBP2_CSR_MANANGEMENT_AGENT        0x30000
+#define SBP2_CSR_COMMAND_BLOCK_AGENT_BASE 0x40000 
+
+#define SBP2_CSR_COMMAND_BLOCK_AGENT_SIZE 0x20
+
+#define SBP2_CSR_MANANGEMENT_OFFSET       (SBP2_CSR_MANANGEMENT_AGENT / 4)
+
+
+#endif /* __SBP2_CSR_H__ */

Added: trunk/libsbp2/sbp2login.h
==============================================================================
--- trunk/libsbp2/sbp2login.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2login.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,39 @@
+#ifndef __SBP2_LOGIN_H__
+#define __SBP2_LOGIN_H__
+
+
+#include <glib.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef struct _SBP2LoginORB SBP2LoginORB;
+typedef struct _SBP2LoginResponse SBP2LoginResponse;
+
+struct _SBP2LoginORB
+{
+  SBP2Pointer password;
+  SBP2Pointer login_resp;
+  guint       lun       : 16;
+  guint       function  : 4;
+  guint       reconnect : 4;
+  guint       reserved  : 4;
+  guint       exclusive : 1;
+  guint       req_fmt   : 2;
+  guint       notify    : 1;
+  guint16     resp_length;
+  guint16     password_length;
+  SBP2Pointer status_FIFO;
+};
+
+struct _SBP2LoginResponse
+{
+  guint16     login_ID;
+  guint16     length;
+  SBP2Pointer command_block_agent;
+  guint16     reconnect_hold;
+  guint16     reserved;
+};
+
+
+#endif /* __SBP2_LOGIN_H__ */

Added: trunk/libsbp2/sbp2logout.h
==============================================================================
--- trunk/libsbp2/sbp2logout.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2logout.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,28 @@
+#ifndef __SBP2_LOGOUT_H__
+#define __SBP2_LOGOUT_H__
+
+
+#include <glib.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef struct _SBP2LogoutORB SBP2LogoutORB;
+
+struct _SBP2LogoutORB
+{
+  guint32     reserved1;
+  guint32     reserved2;
+  guint32     reserved3;
+  guint32     reserved4;
+  guint       login_ID  : 16;
+  guint       function  : 4;
+  guint       reserved  : 9;
+  guint       req_fmt   : 2;
+  guint       notify    : 1;
+  guint32     reserved5;
+  SBP2Pointer status_FIFO;
+};
+
+
+#endif /* __SBP2_LOGOUT_H__ */

Added: trunk/libsbp2/sbp2main.c
==============================================================================
--- trunk/libsbp2/sbp2main.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2main.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,161 @@
+#include <string.h>
+
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include "sbp2byteswap.h"
+#include "sbp2main.h"
+
+
+typedef enum
+{
+  TAG_GENERIC,
+  TAG_ORB,
+  TAG_PAGE
+} TagType;
+
+
+typedef struct _Tag Tag;
+typedef struct _ORBTag ORBTag;
+typedef struct _PageTag PageTag;
+
+struct _Tag
+{
+  TagType  type;
+  gpointer data;
+};
+
+struct _ORBTag
+{
+  Tag             tag;
+
+  raw1394handle_t handle;
+
+  nodeid_t        nodeid;
+  SBP2Pointer     pointer;
+
+  quadlet_t       buffer[8];
+
+  SBP2DispatchORB dispatch;
+};
+
+struct _PageTag
+{
+  Tag tag;
+};
+
+
+static gboolean raw_activity (GIOChannel        *source,
+                              GIOCondition       condition,
+                              gpointer           data);
+                                                                                
+static gint     tag_handler  (raw1394handle_t    handle,
+                              gulong             the_tag,
+                              raw1394_errcode_t  errcode);
+
+
+guint
+sbp2_watch_handle (raw1394handle_t handle)
+{
+  gint        fd;
+  GIOChannel *channel;
+  guint       id;
+
+  raw1394_set_tag_handler (handle, tag_handler);
+
+  fd = raw1394_get_fd (handle);
+
+  channel = g_io_channel_unix_new (fd);
+  id = g_io_add_watch (channel, G_IO_IN | G_IO_PRI, raw_activity, handle);
+  g_io_channel_unref (channel);
+
+  return id;
+}
+
+gint
+sbp2_orb_process (raw1394handle_t  handle,
+                  nodeid_t         nodeid,
+		  SBP2Pointer     *pointer,
+		  SBP2DispatchORB  dispatch,
+		  gpointer         user_data)
+{
+  ORBTag     *orb_tag;
+  nodeaddr_t  address;
+
+  orb_tag = g_new (ORBTag, 1);
+
+  orb_tag->tag.type = TAG_ORB;
+  orb_tag->tag.data = user_data;
+
+  orb_tag->handle = handle;
+
+  orb_tag->nodeid = nodeid;
+  memcpy (&orb_tag->pointer, pointer, sizeof (SBP2Pointer));
+
+  orb_tag->dispatch = dispatch;
+
+  address = sbp2_pointer_to_1394_address (pointer);
+
+  return raw1394_start_read (handle, nodeid, address,
+                             sizeof (orb_tag->buffer), orb_tag->buffer,
+			     (gulong) orb_tag);
+}
+
+gint
+sbp2_write_buffer (raw1394handle_t  handle,
+                   nodeid_t         nodeid,
+                   SBP2Pointer     *pointer,
+		   gpointer         buffer,
+		   gsize            length)
+{
+  Tag        *tag;
+  nodeaddr_t  address;
+
+  tag = g_new (Tag, 1);
+
+  tag->type = TAG_GENERIC;
+  tag->data = buffer;
+
+  address = sbp2_pointer_to_1394_address (pointer);
+
+  return raw1394_start_write (handle, nodeid, address, length,
+                              (quadlet_t *) buffer, (gulong) tag);
+}
+
+static gboolean
+raw_activity (GIOChannel   *source,
+              GIOCondition  condition,
+	      gpointer      data)
+{
+  raw1394handle_t handle = data;
+
+  raw1394_loop_iterate (handle);
+
+  return TRUE;
+}
+
+static gint
+tag_handler (raw1394handle_t   handle,
+             gulong            the_tag,
+             raw1394_errcode_t errcode)
+{
+  Tag *tag = (Tag *) the_tag;
+
+  if (tag->type == TAG_ORB)
+    {
+      ORBTag *orb_tag = (ORBTag *) tag;
+
+      orb_tag->dispatch (orb_tag->handle, orb_tag->nodeid, &orb_tag->pointer,
+	                 orb_tag->buffer, tag->data);
+    }
+  else if (tag->type == TAG_PAGE)
+    {
+    }
+  else
+    g_free (tag->data);
+
+  g_free (tag);
+
+  return 0;
+}

Added: trunk/libsbp2/sbp2main.h
==============================================================================
--- trunk/libsbp2/sbp2main.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2main.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,34 @@
+#ifndef __SBP2_MAIN_H__
+#define __SBP2_MAIN_H__
+
+
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef void (*SBP2DispatchORB) (raw1394handle_t  handle,
+				 nodeid_t         nodeid,
+				 SBP2Pointer     *pointer,
+				 gpointer         the_orb,
+				 gpointer         user_data);
+
+
+guint sbp2_watch_handle (raw1394handle_t  handle);
+
+gint  sbp2_orb_process  (raw1394handle_t  handle,
+                         nodeid_t         nodeid,
+			 SBP2Pointer     *pointer,
+                         SBP2DispatchORB  dispatch,
+			 gpointer         user_data);
+                            
+gint  sbp2_write_buffer (raw1394handle_t  handle,
+                         nodeid_t         nodeid,
+                         SBP2Pointer     *pointer,
+			 gpointer         buffer,
+			 gsize            length);
+
+
+#endif /* __SBP2_MAIN_H__ */

Added: trunk/libsbp2/sbp2manager.c
==============================================================================
--- trunk/libsbp2/sbp2manager.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2manager.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,312 @@
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+#include <libraw1394/csr.h>
+
+#include "sbp2byteswap.h"
+#include "sbp2configrom.h"
+#include "sbp2csr.h"
+#include "sbp2manager.h"
+#include "sbp2main.h"
+#include "sbp2raw1394.h"
+
+
+enum
+{
+  LOGIN_REQUEST        = 0x0,
+  QUERY_LOGINS_REQUEST = 0x1,
+  RECONNECT_REQUEST    = 0x3,
+  SET_PASSWORD_REQUEST = 0x4,
+  LOGOUT_REQUEST       = 0x7,
+  ABORT_TASK_REQUEST   = 0xb,
+  ABORT_TASK_SET       = 0xc,
+  LOGICAL_UNIT_RESET   = 0xe,
+  TARGET_RESET_REQUEST = 0xf
+};
+
+
+typedef struct _SBP2ManagementORB SBP2ManagementORB;
+
+struct _SBP2ManagementORB
+{
+  guint32     reserved1;
+  guint32     reserved2;
+  guint32     reserved3;
+  guint32     reserved4;
+  guint       reserved5 : 16;
+  guint       function  : 4;
+  guint       reserved6 : 9;
+  guint       req_fmt   : 2;
+  guint       notify    : 1;
+  guint32     reserved7;
+  SBP2Pointer status_FIFO;
+};
+
+struct _SBP2Manager
+{
+  raw1394handle_t               handle;
+  guint                         id;
+
+  struct raw1394_arm_reqhandle  arm_management_agent;
+
+  SBP2ManagerFuncs             *funcs;
+  gpointer                      user_data;
+};
+
+
+static gint     management_agent (raw1394handle_t              handle,
+                                  struct arm_request_response *arm_req_resp,
+                                  guint                        requested_length,
+                                  gpointer                     pcontext,
+                                  guint8                       request_type);
+
+static void     dispatch_orb     (raw1394handle_t              handle,
+				  nodeid_t                     nodeid,
+				  SBP2Pointer                 *pointer,
+				  gpointer                     the_orb,
+				  gpointer                     data);
+
+static gboolean login            (SBP2Manager                 *manager,
+                                  nodeid_t                     nodeid,
+				  SBP2Pointer                 *pointer,
+                                  gpointer                     the_orb,
+				  SBP2Status                  *status);
+static gboolean query_logins     (SBP2Manager                 *manager,
+                                  nodeid_t                     nodeid,
+				  SBP2Pointer                 *pointer,
+                                  gpointer                     the_orb,
+				  SBP2Status                  *status);
+static gboolean reconnect        (SBP2Manager                 *manager,
+                                  nodeid_t                     nodeid,
+				  SBP2Pointer                 *pointer,
+                                  gpointer                     the_orb,
+				  SBP2Status                  *status);
+static gboolean logout           (SBP2Manager                 *manager,
+                                  nodeid_t                     nodeid,
+				  SBP2Pointer                 *pointer,
+                                  gpointer                     the_orb,
+				  SBP2Status                  *status);
+
+
+SBP2Manager *
+sbp2_manager_new (SBP2ManagerFuncs *funcs,
+                  gint              port,
+                  gpointer          user_data)
+{
+  SBP2Manager     *manager = NULL;
+  raw1394handle_t  handle = NULL;
+  gint             ret;
+
+  handle = sbp2_raw1394_handle ();
+
+  if (!handle)
+    goto fail;
+
+  if (raw1394_set_port (handle, port) != 0)
+    goto fail;
+
+  if (!sbp2_setup_config_rom (handle))
+    goto fail;
+
+  manager = g_new (SBP2Manager, 1);
+
+  manager->arm_management_agent.arm_callback = management_agent;
+  manager->arm_management_agent.pcontext = manager;
+
+  ret = raw1394_arm_register (handle,
+                              CSR_REGISTER_BASE + SBP2_CSR_MANANGEMENT_AGENT,
+			      8, NULL,
+			      (gulong) &manager->arm_management_agent,
+			      ARM_READ | ARM_WRITE, ARM_WRITE, 0);
+  if (ret < 0)
+    goto fail;
+
+  manager->handle = handle;
+  manager->id = sbp2_watch_handle (handle);
+
+  manager->funcs = funcs;
+  manager->user_data = user_data;
+
+  return manager;
+
+fail:
+  g_free (manager);
+  raw1394_destroy_handle (handle);
+
+  return NULL;
+}
+
+void
+sbp2_manager_destroy (SBP2Manager *manager)
+{
+  g_source_remove (manager->id);
+  
+  raw1394_destroy_handle (manager->handle);
+
+  g_free (manager);
+}
+
+static gint
+management_agent (raw1394handle_t              handle,
+                  struct arm_request_response *arm_req_resp,
+		  guint                        requested_length,
+		  gpointer                     pcontext,
+		  guint8                       request_type)
+{
+  struct arm_request *request;
+  SBP2Manager        *manager = pcontext;
+  SBP2Pointer        *pointer;
+
+  request = arm_req_resp->request;
+
+  pointer = (SBP2Pointer *) request->buffer;
+  sbp2_be32_to_cpu_buffer (pointer, sizeof (SBP2Pointer));
+
+  sbp2_orb_process (handle, request->source_nodeid, pointer,
+                    dispatch_orb, manager);
+
+  return 0;
+}
+
+static void
+dispatch_orb (raw1394handle_t  handle,
+              nodeid_t         nodeid,
+              SBP2Pointer     *pointer,
+	      gpointer         the_orb,
+	      gpointer         data)
+{
+  SBP2ManagementORB *orb = the_orb;
+  SBP2Manager       *manager = data;
+  SBP2Status        *status;
+  gboolean           ret;
+
+  sbp2_be32_to_cpu_buffer (the_orb, 32);
+
+  status = g_new0 (SBP2Status, 1);
+
+  status->len = 1;
+  status->src = SBP2_STATUS_ORGIN_NULL;
+  status->resp = SBP2_STATUS_RESP_REQUEST_COMPLETE;
+
+  switch (orb->function)
+    {
+    case LOGIN_REQUEST:
+      ret = login (manager, nodeid, pointer, orb, status);
+      break;
+
+    case QUERY_LOGINS_REQUEST:
+      ret = query_logins (manager, nodeid, pointer, orb, status);
+      break;
+
+    case RECONNECT_REQUEST:
+      ret = reconnect (manager, nodeid, pointer, orb, status);
+      break;
+
+    case LOGOUT_REQUEST:
+      ret = logout (manager, nodeid, pointer, orb, status);
+      break;
+
+    case SET_PASSWORD_REQUEST:
+    case ABORT_TASK_REQUEST:
+    case ABORT_TASK_SET:
+    case LOGICAL_UNIT_RESET:
+    case TARGET_RESET_REQUEST:
+      /* FIXME: unhandled */
+      ret = FALSE;
+      break;
+    
+    default:
+      /* Error here maybe? */
+      ret = FALSE;
+      break; 
+    }
+
+  if (ret)
+    {
+      sbp2_status_fill_pointer (status, pointer);
+      sbp2_cpu_to_be32_buffer (status, 8);
+      sbp2_write_buffer (handle, nodeid, &orb->status_FIFO, status, 8);
+    }
+  else
+    g_free (status);
+}
+
+static gboolean
+login (SBP2Manager *manager,
+       nodeid_t     nodeid,
+       SBP2Pointer *pointer,
+       gpointer     the_orb,
+       SBP2Status  *status)
+{
+  SBP2LoginORB      *orb = the_orb;
+  SBP2LoginResponse *resp;
+  gint               length;
+
+  resp = g_new0 (SBP2LoginResponse, 1);
+
+  if (!manager->funcs->login (manager, nodeid, pointer, orb, resp, status,
+	                      manager->user_data))
+    {
+      g_free (resp);
+      return FALSE;
+    }
+
+  length = resp->length;
+
+  sbp2_cpu_to_be32_buffer (resp, length);
+  sbp2_write_buffer (manager->handle, nodeid, &orb->login_resp, resp, length);
+
+  return TRUE;
+}
+
+static gboolean
+query_logins (SBP2Manager *manager,
+              nodeid_t     nodeid,
+              SBP2Pointer *pointer,
+              gpointer     the_orb,
+              SBP2Status  *status)
+{
+  SBP2QueryLoginsORB      *orb = the_orb;
+  SBP2QueryLoginsResponse *resp;
+
+  resp = g_new0 (SBP2QueryLoginsResponse, 1);
+
+  if (!manager->funcs->query_logins (manager, nodeid, pointer, orb, resp,
+	                             status, manager->user_data))
+    {
+      g_free (resp);
+      return FALSE;
+    }
+
+  sbp2_cpu_to_be32_buffer (resp, 8);
+  sbp2_write_buffer (manager->handle, nodeid, &orb->query_resp,
+		     resp, resp->length);
+
+  return TRUE;
+}
+
+static gboolean
+reconnect (SBP2Manager *manager,
+           nodeid_t     nodeid,
+           SBP2Pointer *pointer,
+           gpointer     the_orb,
+           SBP2Status  *status)
+{
+  SBP2ReconnectORB *orb = the_orb;
+
+  return manager->funcs->reconnect (manager, nodeid, pointer, orb, status,
+                                    manager->user_data);
+}
+
+static gboolean
+logout (SBP2Manager *manager,
+        nodeid_t     nodeid,
+        SBP2Pointer *pointer,
+        gpointer     the_orb,
+        SBP2Status  *status)
+{
+  SBP2LogoutORB *orb = the_orb;
+
+  return manager->funcs->logout (manager, nodeid, pointer, orb, status,
+                                 manager->user_data);
+}

Added: trunk/libsbp2/sbp2manager.h
==============================================================================
--- trunk/libsbp2/sbp2manager.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2manager.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,59 @@
+#ifndef __SBP2_MANAGER_H__
+#define __SBP2_MANAGER_H__
+
+
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include <libsbp2/sbp2login.h>
+#include <libsbp2/sbp2logout.h>
+#include <libsbp2/sbp2querylogins.h>
+#include <libsbp2/sbp2reconnect.h>
+#include <libsbp2/sbp2status.h>
+
+
+typedef struct _SBP2Manager SBP2Manager;
+typedef struct _SBP2ManagerFuncs SBP2ManagerFuncs;
+
+struct _SBP2ManagerFuncs
+{
+  gboolean (*login)        (SBP2Manager             *manager,
+                            nodeid_t                 nodeid,
+			    SBP2Pointer             *pointer,
+                            SBP2LoginORB            *orb,
+                            SBP2LoginResponse       *resp,
+                            SBP2Status              *status,
+                            gpointer                 user_data);
+  gboolean (*query_logins) (SBP2Manager             *manager,
+                            nodeid_t                 nodeid,
+			    SBP2Pointer             *pointer,
+                            SBP2QueryLoginsORB      *orb,
+                            SBP2QueryLoginsResponse *resp,
+                            SBP2Status              *status,
+                            gpointer                 user_data);
+  gboolean (*reconnect)    (SBP2Manager             *manager,
+                            nodeid_t                 nodeid,
+			    SBP2Pointer             *pointer,
+                            SBP2ReconnectORB        *orb,
+                            SBP2Status              *status,
+                            gpointer                 user_data);
+  gboolean (*logout)       (SBP2Manager             *manager,
+                            nodeid_t                 nodeid,
+			    SBP2Pointer             *pointer,
+                            SBP2LogoutORB           *orb,
+                            SBP2Status              *status,
+                            gpointer                 user_data);
+
+  /* TODO: task_management */
+};
+
+
+SBP2Manager *sbp2_manager_new     (SBP2ManagerFuncs *funcs,
+                                   gint              port,
+                                   gpointer          user_data);
+
+void         sbp2_manager_destroy (SBP2Manager      *manager);
+
+
+#endif /* __SBP2_MANAGER_H__ */

Added: trunk/libsbp2/sbp2pagetable.h
==============================================================================
--- trunk/libsbp2/sbp2pagetable.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2pagetable.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,26 @@
+#ifndef __SBP2_PAGE_TABLE_H__
+#define __SBP2_PAGE_TABLE_H__
+
+
+#include <glib.h>
+
+
+typedef struct _SBP2PageTable SBP2PageTable;
+typedef struct _SBP2PageTableNormalized SBP2PageTableNormalized;
+
+struct _SBP2PageTable
+{
+  guint   segment_base_hi : 16;
+  guint   segment_length  : 16;
+  guint32 segment_base_lo;
+};
+
+struct _SBP2PageTableNormalized
+{
+  /* TODO */
+  guint32 unimplmented1;
+  guint32 unimplmented2;
+};
+
+
+#endif /* __SBP2_PAGE_TABLE_H__ */

Added: trunk/libsbp2/sbp2pointer.h
==============================================================================
--- trunk/libsbp2/sbp2pointer.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2pointer.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,45 @@
+#ifndef __SBP2_POINTER_H__
+#define __SBP2_POINTER_H__
+
+
+#include <glib.h>
+
+
+typedef struct _SBP2Pointer SBP2Pointer;
+
+struct _SBP2Pointer
+{
+  guint   addr_hi : 16;
+  guint   nodeid  : 16;
+  guint32 addr_lo;
+};
+
+
+static inline guint64
+sbp2_pointer_to_1394_address (SBP2Pointer *p)
+{
+  guint64 address;
+
+  address = p->addr_lo;
+  address |= (guint64) p->addr_hi << 32;
+
+  return address;
+}
+
+static inline void
+sbp2_pointer_from_1394_address (SBP2Pointer *p,
+                                guint64      address)
+{
+  p->addr_lo = address & 0xffffffff;
+  p->addr_hi |= (address >> 32) & 0xffff;
+}
+
+
+static inline gboolean
+sbp2_pointer_is_null_orb (SBP2Pointer *p)
+{
+  return p->nodeid & 0x8000;
+}
+
+
+#endif /* __SBP2_POINTER_H__ */

Added: trunk/libsbp2/sbp2querylogins.h
==============================================================================
--- trunk/libsbp2/sbp2querylogins.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2querylogins.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,37 @@
+#ifndef __SBP2_QUERY_LOGINS_H__
+#define __SBP2_QUERY_LOGINS_H__
+
+
+#include <glib.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef struct _SBP2QueryLoginsORB SBP2QueryLoginsORB;
+typedef struct _SBP2QueryLoginsResponse SBP2QueryLoginsResponse;
+
+struct _SBP2QueryLoginsORB
+{
+  guint32     reserved1;
+  guint32     reserved2;
+  SBP2Pointer query_resp;
+  guint       lun          : 16;
+  guint       function     : 4;
+  guint       reserved3    : 9;
+  guint       req_fmt      : 2;
+  guint       notify       : 1;
+  guint       resp_length  : 16;
+  guint       reserved4    : 16;
+  SBP2Pointer status_FIFO;
+};
+
+struct _SBP2QueryLoginsResponse
+{
+  guint max_logins : 16;
+  guint length     : 16;
+
+  /* TODO: Logged in initiator listing here, ignored for now */
+};
+
+
+#endif /* __SBP2_QUERY_LOGINS_H__ */

Added: trunk/libsbp2/sbp2raw1394.c
==============================================================================
--- trunk/libsbp2/sbp2raw1394.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2raw1394.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,41 @@
+#include <errno.h>
+
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include "sbp2raw1394.h"
+
+
+static const gchar *errmsg_not_compatible =
+"This libraw1394 does not work with your version of Linux. You need a "
+"different version that matches your kernel (see kernel help text for the "
+"raw1394 option to find out which is the correct version).";
+
+static const gchar *errmsg_not_loaded =
+"This probably means that you don't have raw1394 support in the kernel or "
+"that you haven't loaded the raw1394 module.";
+
+
+raw1394handle_t
+sbp2_raw1394_handle (void)
+{
+  raw1394handle_t handle;
+
+  handle = raw1394_new_handle ();
+
+  if (!handle)
+    {
+      if (!errno)
+	{
+	  g_critical (errmsg_not_compatible);
+	}
+      else
+	{
+	  g_critical ("Couldn't get handle");
+	  g_critical (errmsg_not_loaded);
+	}
+    }
+
+  return handle;
+}

Added: trunk/libsbp2/sbp2raw1394.h
==============================================================================
--- trunk/libsbp2/sbp2raw1394.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2raw1394.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,11 @@
+#ifndef __SBP2_RAW1394_H__
+#define __SBP2_RAW1394_H__
+
+
+#include <libraw1394/raw1394.h>
+
+
+raw1394handle_t sbp2_raw1394_handle (void);
+
+
+#endif /* __SBP2_RAW1394_H__ */

Added: trunk/libsbp2/sbp2reconnect.h
==============================================================================
--- trunk/libsbp2/sbp2reconnect.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2reconnect.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,28 @@
+#ifndef __SBP2_RECONNECT_H__
+#define __SBP2_RECONNECT_H__
+
+
+#include <glib.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef struct _SBP2ReconnectORB SBP2ReconnectORB;
+
+struct _SBP2ReconnectORB
+{
+  guint32     reserved1;
+  guint32     reserved2;
+  guint32     reserved3;
+  guint32     reserved4;
+  guint       login_ID  : 16;
+  guint       function  : 4;
+  guint       reserved  : 9;
+  guint       req_fmt   : 2;
+  guint       notify    : 1;
+  guint32     reserved5;
+  SBP2Pointer status_FIFO;
+};
+
+
+#endif /* __SBP2_RECONNECT_H__ */

Added: trunk/libsbp2/sbp2scsicommand.h
==============================================================================
--- trunk/libsbp2/sbp2scsicommand.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2scsicommand.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,29 @@
+#ifndef __SBP2_SCSI_COMMAND_H__
+#define __SBP2_SCSI_COMMAND_H__
+
+
+#include <glib.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef struct _SBP2ScsiCommandORB SBP2ScsiCommandORB;
+
+struct _SBP2ScsiCommandORB
+{
+  SBP2Pointer next_ORB;
+  SBP2Pointer data_desc;
+  guint       data_size      : 16;
+  guint       page_size      : 3;
+  guint       has_page_table : 1;
+  guint       max_payload    : 4;
+  guint       speed          : 3;
+  guint       direction      : 1;
+  guint       reserved       : 1;
+  guint       req_fmt        : 2;
+  guint       notify         : 1;
+  guint8      cdb[12];
+};
+
+
+#endif /* __SBP2_SCSI_COMMAND_H__ */

Added: trunk/libsbp2/sbp2scsistatus.h
==============================================================================
--- trunk/libsbp2/sbp2scsistatus.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2scsistatus.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,36 @@
+#ifndef __SBP2_SCSI_STATUS_H__
+#define __SBP2_SCSI_STATUS_H__
+
+
+#include <glib.h>
+
+
+typedef struct _SBP2ScsiStatus SBP2ScsiStatus;
+
+struct _SBP2ScsiStatus
+{
+  guint   ORB_hi          : 16;
+  guint   sbp_status      : 8;
+  guint   len             : 3;
+  guint   dead            : 1;
+  guint   resp            : 2;
+  guint   src             : 2;
+  guint32 ORB_lo;
+  guint   sense_qualifier : 8;
+  guint   sense_code      : 8;
+  guint   sense_key       : 4;
+  guint   ili             : 1;
+  guint   eom             : 1;
+  guint   mark            : 1;
+  guint   valid           : 1;
+  guint   status          : 6;
+  guint   sfmt            : 2;
+  guint32 information;
+  guint32 cdb_dependent;
+  guint   sense_key_dep   : 12;
+  guint   fru             : 8;
+
+};
+
+
+#endif /* __SBP2_SCSI_STATUS_H__ */

Added: trunk/libsbp2/sbp2status.h
==============================================================================
--- trunk/libsbp2/sbp2status.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2status.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,70 @@
+#ifndef __SBP2_STATUS_H__
+#define __SBP2_STATUS_H__
+
+
+#include <glib.h>
+
+#include <libsbp2/sbp2pointer.h>
+
+
+typedef enum
+{
+  SBP2_STATUS_ORGIN_NON_NULL    = 0x0,
+  SBP2_STATUS_ORGIN_NULL        = 0x1,
+  SBP2_STATUS_ORGIN_UNSOLICITED = 0x2,
+  SBP2_STATUS_ORGIN_RESERVED    = 0x3
+} SBP2StatusOrigin;
+
+typedef enum
+{
+  SBP2_STATUS_RESP_REQUEST_COMPLETE  = 0x0,
+  SBP2_STATUS_RESP_TRANSPORT_FAILURE = 0x1,
+  SBP2_STATUS_RESP_ILLEGAL_REQUEST   = 0x2,
+  SBP2_STATUS_RESP_VENDOR_DEPENDENT  = 0x3
+} SBP2StatusResponse;
+
+typedef enum
+{
+  SBP2_STATUS_REQUEST_NO_ADDITIONAL_INFO      = 0x0,
+  SBP2_STATUS_REQUEST_REQ_TYPE_NOT_SUPPORTED  = 0x1,
+  SBP2_STATUS_REQUEST_SPEED_NOT_SUPPORTED     = 0x2,
+  SBP2_STATUS_REQUEST_PAGE_SIZE_NOT_SUPPORTED = 0x3,
+  SBP2_STATUS_REQUEST_ACCESS_DENIED           = 0x4,
+  SBP2_STATUS_REQUEST_LU_NOT_SUPPORTED        = 0x5,
+  SBP2_STATUS_REQUEST_MAX_PAYLOAD_TOO_SMALL   = 0x6,
+  SBP2_STATUS_REQUEST_RESOURCES_UNAVAILABLE   = 0x8,
+  SBP2_STATUS_REQUEST_FUNCTION_REJECTED       = 0x9,
+  SBP2_STATUS_REQUEST_LOGIN_ID_NOT_RECOGNIZED = 0xa,
+  SBP2_STATUS_REQUEST_DUMMY_ORB_COMPLETED     = 0xb,
+  SBP2_STATUS_REQUEST_REQUEST_ABORTED         = 0xc,
+  SBP2_STATUS_REQUEST_UNSPECIFIED_ERROR       = 0xff
+} SBP2StatusRequest;
+
+/* TODO: transport failure error codes */
+
+
+typedef struct _SBP2Status SBP2Status;
+
+struct _SBP2Status
+{
+  guint   ORB_hi     : 16;
+  guint   sbp_status : 8;
+  guint   len        : 3;
+  guint   dead       : 1;
+  guint   resp       : 2;
+  guint   src        : 2;
+  guint32 ORB_lo;
+  guint8  sense[24];
+};
+
+
+static inline void
+sbp2_status_fill_pointer (SBP2Status  *s,
+                          SBP2Pointer *p)
+{
+  s->ORB_hi = p->addr_hi;
+  s->ORB_lo = p->addr_lo;
+}
+
+
+#endif /* __SBP2_STATUS_H__ */

Added: trunk/libsbp2/sbp2worker.c
==============================================================================
--- trunk/libsbp2/sbp2worker.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2worker.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,392 @@
+#include <string.h>
+
+#include <glib.h>
+ 
+#include <libraw1394/raw1394.h>
+#include <libraw1394/csr.h>
+
+#include <librbc/rbcdisk.h>
+#include <librbc/rbccommand.h>
+
+#include "sbp2byteswap.h"
+#include "sbp2constants.h"
+#include "sbp2csr.h"
+#include "sbp2main.h"
+#include "sbp2raw1394.h"
+#include "sbp2scsicommand.h"
+#include "sbp2status.h"
+#include "sbp2worker.h"
+
+
+enum
+{
+  CMD_AGENT_STATE               = 0x00,
+  CMD_AGENT_RESET               = 0x04,
+  CMD_ORB_POINTER               = 0x08,
+  CMD_DOORBELL                  = 0x10,
+  CMD_UNSOLICITED_STATUS_ENABLE = 0x14
+};
+
+typedef enum
+{
+  STATE_RESET     = 0x0,
+  STATE_ACTIVE    = 0x1,
+  STATE_SUSPENDED = 0x2,
+  STATE_DEAD      = 0x3
+} State;
+
+
+struct _SBP2Worker
+{
+  raw1394handle_t               handle;
+  guint                         id;
+
+  RBCDisk                      *disk;
+
+  State                         state;
+  gboolean                      doorbell;
+
+  SBP2Pointer                  *pointer;
+
+  nodeaddr_t                    csr_address;
+  SBP2Pointer                   status_FIFO;
+
+  struct raw1394_arm_reqhandle  arm_agent_state;
+  struct raw1394_arm_reqhandle  arm_agent_reset;
+  struct raw1394_arm_reqhandle  arm_orb_pointer;
+  struct raw1394_arm_reqhandle  arm_doorbell;
+  struct raw1394_arm_reqhandle  arm_unsolicited_status_enable;
+};
+
+
+static gint     agent_reset               (raw1394handle_t              handle,
+                                           struct arm_request_response *arm_req_resp,
+					   guint                        requested_length,
+					   gpointer                     pcontext,
+					   guint8                       request_type);
+static gint     orb_pointer               (raw1394handle_t              handle,
+                                           struct arm_request_response *arm_req_resp,
+					   guint                        requested_length,
+					   gpointer                     pcontext,
+					   guint8                       request_type);
+static gint     doorbell                  (raw1394handle_t              handle,
+                                           struct arm_request_response *arm_req_resp,
+					   guint                        requested_length,
+					   gpointer                     pcontext,
+					   guint8                       request_type);
+static gint     unsolicited_status_enable (raw1394handle_t              handle,
+                                           struct arm_request_response *arm_req_resp,
+					   guint                        requested_length,
+					   gpointer                     pcontext,
+					   guint8                       request_type);
+
+static void     dispatch_orb              (raw1394handle_t              handle,
+                                           nodeid_t                     nodeid,
+					   SBP2Pointer                 *pointer,
+					   gpointer                     the_orb,
+					   gpointer                     data);
+
+static gint     write_buffer              (raw1394handle_t              handle,
+                                           nodeid_t                     nodeid,
+					   gint                         max_payload,
+					   SBP2Pointer                 *pointer,
+					   RBCBuffer                   *buffer);
+
+
+SBP2Worker *
+sbp2_worker_new (RBCDisk  *disk,
+                 gint      port,
+                 guint     slot)
+{
+  SBP2Worker      *worker = NULL;
+  raw1394handle_t  handle;
+  nodeaddr_t       csr_address;
+  gint             ret;
+
+  handle = sbp2_raw1394_handle ();
+
+  if (!handle)
+    return NULL;
+
+  if (raw1394_set_port (handle, port) != 0)
+    goto fail;
+
+  csr_address = CSR_REGISTER_BASE + SBP2_CSR_COMMAND_BLOCK_AGENT_BASE +
+                (SBP2_CSR_COMMAND_BLOCK_AGENT_SIZE * slot);
+
+  worker = g_new (SBP2Worker, 1);
+
+  /* TODO: Way to update the register */
+  ret = raw1394_arm_register (handle,
+                              csr_address + CMD_AGENT_STATE,
+			      4, NULL,
+                              0,
+			      ARM_READ, 0, 0);
+  if (ret < 0)
+    goto fail;
+
+  worker->arm_agent_reset.arm_callback = agent_reset;
+  worker->arm_agent_reset.pcontext = worker;
+
+  ret = raw1394_arm_register (handle,
+                              csr_address + CMD_AGENT_RESET,
+			      4, NULL,
+                              (gulong) &worker->arm_agent_reset,
+			      ARM_WRITE, ARM_WRITE, 0);
+  if (ret < 0)
+    goto fail;
+
+  worker->arm_orb_pointer.arm_callback = orb_pointer;
+  worker->arm_orb_pointer.pcontext = worker;
+
+  ret = raw1394_arm_register (handle,
+                              csr_address + CMD_ORB_POINTER,
+			      8, NULL,
+                              (gulong) &worker->arm_orb_pointer,
+			      ARM_READ | ARM_WRITE, ARM_WRITE, 0);
+  if (ret < 0)
+    goto fail;
+
+  worker->arm_doorbell.arm_callback = doorbell;
+  worker->arm_doorbell.pcontext = worker;
+
+  ret = raw1394_arm_register (handle,
+                              csr_address + CMD_DOORBELL,
+			      4, NULL,
+                              (gulong) &worker->arm_doorbell,
+			      ARM_WRITE, ARM_WRITE, 0);
+  if (ret < 0)
+    goto fail;
+
+  worker->arm_unsolicited_status_enable.arm_callback = unsolicited_status_enable;
+  worker->arm_unsolicited_status_enable.pcontext = worker;
+
+  ret = raw1394_arm_register (handle,
+                              csr_address + CMD_UNSOLICITED_STATUS_ENABLE,
+			      4, NULL,
+                              (gulong) &worker->arm_unsolicited_status_enable,
+			      ARM_WRITE, ARM_WRITE, 0);
+  if (ret < 0)
+    goto fail;
+
+  worker->disk = disk;
+
+  worker->state = STATE_RESET;
+
+  worker->csr_address = csr_address;
+
+  worker->handle = handle;
+  worker->id = sbp2_watch_handle (handle);
+
+  return worker;
+
+fail:
+  g_free (worker);
+  raw1394_destroy_handle (handle);
+
+ return NULL; 
+}
+
+void
+sbp2_worker_destroy (SBP2Worker *worker)
+{
+  g_source_remove (worker->id);
+
+  raw1394_destroy_handle (worker->handle);
+
+  g_free (worker);
+}
+
+gboolean
+sbp2_worker_login (SBP2Worker   *worker,
+                   nodeid_t      nodeid,
+		   SBP2Pointer  *pointer,
+                   SBP2LoginORB *orb,
+		   guint16       login_ID)
+{
+  SBP2LoginResponse *resp;
+  SBP2Status        *status;
+  gint               length;
+
+  memcpy (&worker->status_FIFO, &orb->status_FIFO, sizeof (SBP2Pointer));
+
+  resp = g_new (SBP2LoginResponse, 1);
+
+  if (orb->resp_length >= 16)
+    resp->length = length = 16;
+  else
+    resp->length = length = 12;
+
+  resp->login_ID = login_ID;
+
+  resp->reconnect_hold = SBP2_RECONNECT_HOLD;
+
+  resp->command_block_agent.nodeid = raw1394_get_local_id (worker->handle);
+
+  sbp2_pointer_from_1394_address (&resp->command_block_agent,
+                                  worker->csr_address);
+
+  sbp2_cpu_to_be32_buffer (resp, length);
+  sbp2_write_buffer (worker->handle, nodeid, &orb->login_resp, resp, length);
+
+  status = g_new (SBP2Status, 1);
+
+  status->len = 1;
+  status->src = SBP2_STATUS_ORGIN_NULL;
+  status->resp = SBP2_STATUS_RESP_REQUEST_COMPLETE;
+
+  sbp2_status_fill_pointer (status, pointer);
+  sbp2_cpu_to_be32_buffer (status, 8);
+  sbp2_write_buffer (worker->handle, nodeid, &orb->status_FIFO, status, 8);
+
+  return TRUE;
+}
+
+static gint
+agent_reset (raw1394handle_t              handle,
+             struct arm_request_response *arm_req_resp,
+	     guint                        requested_length,
+	     gpointer                     pcontext,
+	     guint8                       request_type)
+{
+  SBP2Worker *worker = pcontext;
+
+  worker->state = STATE_RESET;
+  worker->doorbell = 0;
+
+  return 0;
+}
+
+static gint
+orb_pointer (raw1394handle_t              handle,
+             struct arm_request_response *arm_req_resp,
+	     guint                        requested_length,
+	     gpointer                     pcontext,
+	     guint8                       request_type)
+{
+  struct arm_request *request;
+  SBP2Worker *worker = pcontext;
+  SBP2Pointer        *pointer;
+ 
+  if (worker->state == STATE_DEAD)
+    return 0;
+
+  request = arm_req_resp->request;
+
+  worker->state = STATE_ACTIVE;
+  worker->doorbell = 0;
+ 
+  pointer = (SBP2Pointer *) request->buffer;
+  sbp2_be32_to_cpu_buffer (pointer, sizeof (SBP2Pointer));
+
+  sbp2_orb_process (handle, request->source_nodeid, pointer,
+                    dispatch_orb, worker);
+
+  return 0;
+}
+
+static gint
+doorbell (raw1394handle_t              handle,
+          struct arm_request_response *arm_req_resp,
+	  guint                        requested_length,
+	  gpointer                     pcontext,
+	  guint8                       request_type)
+{
+  struct arm_request *request;
+  SBP2Worker *worker = pcontext;
+ 
+  if (worker->state != STATE_SUSPENDED)
+    return 0;
+
+  request = arm_req_resp->request;
+
+  worker->state = STATE_ACTIVE;
+
+  sbp2_orb_process (handle, request->source_nodeid, worker->pointer,
+                    dispatch_orb, worker);
+
+  return 0;
+}
+
+
+static gint
+unsolicited_status_enable (raw1394handle_t              handle,
+			   struct arm_request_response *arm_req_resp,
+			   guint                        requested_length,
+			   gpointer                     pcontext,
+			   guint8                       request_type)
+{
+  /* TODO */
+  return 0;
+}
+
+static void
+dispatch_orb (raw1394handle_t  handle,
+              nodeid_t         nodeid,
+	      SBP2Pointer     *pointer,
+	      gpointer         the_orb,
+              gpointer         data)
+{
+  SBP2ScsiCommandORB *orb = the_orb;
+  SBP2Worker         *worker = data;
+  SBP2Status         *status;
+  RBCBuffer           buffer;
+  gint                length;
+
+  sbp2_be32_to_cpu_buffer (the_orb, 20);
+
+  status = g_new0 (SBP2Status, 1);
+
+  status->len = 1;
+  status->resp = SBP2_STATUS_RESP_REQUEST_COMPLETE;
+
+  if (!sbp2_pointer_is_null_orb (&orb->next_ORB))
+    {
+      status->src = SBP2_STATUS_ORGIN_NON_NULL;
+      sbp2_orb_process (handle, nodeid, &orb->next_ORB, dispatch_orb, worker);
+    }
+  else
+    status->src = SBP2_STATUS_ORGIN_NULL;
+
+  if (orb->req_fmt == 0x0)
+    {
+      if (orb->has_page_table)
+	{
+	}
+      else if (orb->data_size)
+	{
+	  buffer.type = RBC_BUFFER_TYPE_SIMPLE;
+	  buffer.length = orb->data_size; 
+	  buffer.data = g_malloc (buffer.length);
+	}
+      else
+	buffer.type = RBC_BUFFER_TYPE_EMPTY;
+
+      if (rbc_disk_command (worker->disk, orb->cdb, &buffer, status->sense))
+	{
+	  if (buffer.type == RBC_BUFFER_TYPE_SIMPLE && orb->direction)
+	    write_buffer (handle, nodeid, orb->max_payload, &orb->data_desc,
+		          buffer.data, buffer.length);
+        }
+      else
+	status->len = 7;
+    }
+
+  length = (status->len + 1) * 4;
+
+  sbp2_status_fill_pointer (status, pointer);
+  sbp2_cpu_to_be32_buffer (status, 8);
+  sbp2_write_buffer (handle, nodeid, &worker->status_FIFO, status, length);
+}
+
+static gint
+write_buffer (raw1394handle_t  handle,
+              nodeid_t         nodeid,
+	      gint             max_payload,
+	      SBP2Pointer     *pointer,
+	      RBCBuffer       *buffer)
+{
+  gint length;
+
+  for (length = buffer->length; length > 0; length 
+}

Added: trunk/libsbp2/sbp2worker.h
==============================================================================
--- trunk/libsbp2/sbp2worker.h	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/libsbp2/sbp2worker.h	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,34 @@
+#ifndef __SBP2_WORKER_H__
+#define __SBP2_WORKER_H__
+
+
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include <librbc/rbcdisk.h>
+
+#include <libsbp2/sbp2pointer.h>
+#include <libsbp2/sbp2login.h>
+
+
+typedef struct _SBP2Worker SBP2Worker;
+
+
+SBP2Worker *sbp2_worker_new       (RBCDisk      *disk,
+				   gint          port,
+				   guint         slot);
+
+void        sbp2_worker_destroy   (SBP2Worker   *worker);
+
+gboolean    sbp2_worker_login     (SBP2Worker   *worker,
+				   nodeid_t      nodeid,
+				   SBP2Pointer  *pointer,
+				   SBP2LoginORB *orb,
+				   guint16       login_ID);
+
+gboolean    sbp2_worker_reconnect (SBP2Worker   *worker,
+                                   nodeid_t      nodeid);
+
+
+#endif /* __SBP2_WORKER_H__ */

Added: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/src/Makefile.am	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,15 @@
+bin_PROGRAMS = endpoint
+
+INCLUDES = \
+	-I$(top_srcdir)	\
+	$(GLIB_CFLAGS)	\
+	-I$(includedir)
+
+endpoint_SOURCES = \
+	main.c
+
+endpoint_LDADD = \
+	$(top_builddir)/libsbp2/libendpointsbp2.la	\
+	$(top_builddir)/librbc/libendpointrbc.la	\
+	$(GLIB_LIBS)					\
+	-lraw1394

Added: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	2003-07-07 10:35:55 UTC (rev 1)
+++ trunk/src/main.c	2003-07-07 10:38:37 UTC (rev 2)
@@ -0,0 +1,220 @@
+/*
+ * Endpoint - Linux SBP2 Disk Target
+ *
+ * Copyright (C) 2003 Oracle.  All rights reserved.
+ *
+ * Author: Manish Singh <manish.singh at oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have recieved a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include <libraw1394/raw1394.h>
+
+#include "librbc/rbcmanage.h"
+
+#include "libsbp2/sbp2manager.h"
+#include "libsbp2/sbp2raw1394.h"
+#include "libsbp2/sbp2worker.h"
+
+
+#define CONFFILE "/usr/local/etc/endpoint.conf"
+
+#define MAXPORTS  8
+#define MAXLOGINS 4
+
+
+typedef struct _Port Port;
+
+struct _Port
+{
+  SBP2Manager *manager;
+  gint         num;
+  SBP2Worker  *workers[4];
+};
+
+static gint     get_num_ports (void);
+
+static gboolean query_logins  (SBP2Manager             *manager,
+                               nodeid_t                 nodeid,
+			       SBP2Pointer             *pointer,
+                               SBP2QueryLoginsORB      *orb,
+			       SBP2QueryLoginsResponse *resp,
+			       SBP2Status              *status,
+			       gpointer                 user_data);
+static gboolean login         (SBP2Manager             *manager,
+                               nodeid_t                 nodeid,
+			       SBP2Pointer             *pointer,
+                               SBP2LoginORB            *orb,
+			       SBP2LoginResponse       *resp,
+			       SBP2Status              *status,
+			       gpointer                 user_data);
+static gboolean reconnect     (SBP2Manager             *manager,
+                               nodeid_t                 nodeid,
+			       SBP2Pointer             *pointer,
+                               SBP2ReconnectORB        *orb,
+			       SBP2Status              *status,
+			       gpointer                 user_data);
+static gboolean logout        (SBP2Manager             *manager,
+                               nodeid_t                 nodeid,
+			       SBP2Pointer             *pointer,
+                               SBP2LogoutORB           *orb,
+			       SBP2Status              *status,
+			       gpointer                 user_data);
+
+
+Port ports[MAXPORTS];
+
+SBP2ManagerFuncs manager_funcs = {
+  login,
+  query_logins,
+  reconnect,
+  logout
+};
+
+
+int
+main (int   argc,
+      char *argv[])
+{
+  gchar           *conffile = CONFFILE;
+  gint             num_ports, i;
+  SBP2Manager     *manager;
+  GMainLoop       *loop;
+
+  if (argc > 1)
+    conffile = argv[1];
+
+  for (i = 0; i < MAXPORTS; i++)
+    ports[i].manager = NULL;
+
+  num_ports = get_num_ports ();
+
+  if (num_ports == 0)
+    exit (1);
+
+  if (num_ports > MAXPORTS)
+    num_ports = MAXPORTS;
+
+  for (i = 0; i < num_ports; i++)
+    {
+       ports[i].num = i;
+
+       manager = sbp2_manager_new (&manager_funcs, i, &ports[i]);
+       
+       if (manager)
+	 ports[i].manager = manager;
+       else
+         exit (1);
+    }
+
+  loop = g_main_loop_new (NULL, TRUE);
+
+  g_main_loop_run (loop);
+
+  g_main_loop_unref (loop);
+
+  for (i = 0; i < MAXPORTS; i++)
+    if (ports[i].manager)
+      sbp2_manager_destroy (ports[i].manager);
+
+  return 0;
+}
+
+static gint
+get_num_ports (void)
+{
+  raw1394handle_t handle;
+  gint            num_ports;
+       
+  handle = sbp2_raw1394_handle ();
+	 
+  if (!handle)
+    return 0;
+	   
+  num_ports = raw1394_get_port_info (handle, NULL, 0);
+	     
+  raw1394_destroy_handle (handle);
+	       
+  return num_ports;
+}
+
+static gboolean
+query_logins (SBP2Manager             *manager,
+              nodeid_t                 nodeid,
+	      SBP2Pointer             *pointer,
+              SBP2QueryLoginsORB      *orb,
+	      SBP2QueryLoginsResponse *resp,
+	      SBP2Status              *status,
+	      gpointer                 user_data)
+{
+  resp->length = 12;
+  resp->max_logins = MAXLOGINS;
+
+  return TRUE;
+}
+
+static gboolean
+login (SBP2Manager       *manager,
+       nodeid_t           nodeid,
+       SBP2Pointer       *pointer,
+       SBP2LoginORB      *orb,
+       SBP2LoginResponse *resp,
+       SBP2Status        *status,
+       gpointer           user_data)
+{
+  SBP2Worker *worker;
+  Port       *port = user_data;
+
+  worker = sbp2_worker_new (rbc_disk_new (), port->num, 0);
+
+  if (!worker)
+    {
+      status->sbp_status = SBP2_STATUS_REQUEST_RESOURCES_UNAVAILABLE;
+      return TRUE;
+    }
+
+  sbp2_worker_login (worker, nodeid, pointer, orb, 0);
+
+  return FALSE;
+}
+
+static gboolean
+reconnect (SBP2Manager      *manager,
+           nodeid_t          nodeid,
+           SBP2Pointer      *pointer,
+	   SBP2ReconnectORB *orb,
+	   SBP2Status       *status,
+	   gpointer          user_data)
+{
+  return FALSE;
+}
+
+static gboolean
+logout (SBP2Manager   *manager,
+        nodeid_t       nodeid,
+        SBP2Pointer   *pointer,
+	SBP2LogoutORB *orb,
+	SBP2Status    *status,
+	gpointer       user_data)
+{
+  return FALSE;
+}



More information about the Endpoint-commits mailing list