[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