haiku/headers/private/kernel/boot/net/iSCSITarget.h
Andreas Färber 5b086e27e8 boot_net: Add iSCSI initiator support
Add support for both discovery and regular iSCSI sessions. Command and status
sequence numbers do differentiate between session and connection but only
one connection per session is currently supported.

Code is Big Endian for now, so compile it for ppc only.

Based on RFC 3720 ff. Tested against OpenSolaris 2009.06.

Resolves most of ticket #5319.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38536 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-09-05 22:30:41 +00:00

109 lines
2.8 KiB
C++

/*
* Copyright 2010, Andreas Färber <andreas.faerber@web.de>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef BOOT_NET_ISCSITARGET_H
#define BOOT_NET_ISCSITARGET_H
#include <SupportDefs.h>
#include <util/kernel_cpp.h>
#include <boot/platform.h>
#include <boot/stdio.h>
#include <boot/vfs.h>
#include <boot/net/NetDefs.h>
#define ISCSI_PORT 3260
class TCPSocket;
class iSCSISession;
struct iscsi_basic_header_segment;
#define kTcpTimeout 10000000ULL
class iSCSIConnection {
public:
iSCSIConnection();
virtual ~iSCSIConnection();
status_t Init(iSCSISession* session);
status_t Open(ip_addr_t address, uint16 port);
status_t Login(const char* targetName = NULL, char** targetAlias = NULL);
status_t Logout(bool closeSession = false);
status_t GetText(const char* request, size_t requestLength, char** response, size_t* responseLength);
status_t SendCommand(const void* command, size_t commandSize,
bool r, bool w, uint32 expectedDataTransferLength,
void* response, uint32 responseOffset, size_t responseLength);
bool Active() const { return fConnected; }
private:
status_t _ReadResponse(iscsi_basic_header_segment* buffer, bigtime_t timeout = kTcpTimeout);
status_t _Read(void* buffer, size_t bufferSize, bigtime_t timeout = kTcpTimeout);
iSCSISession* fSession;
TCPSocket* fSocket;
bool fConnected;
uint16 fConnectionID;
uint32 fStatusSequenceNumber;
};
class iSCSISession {
public:
iSCSISession(const char* targetName = NULL);
virtual ~iSCSISession();
status_t Init(ip_addr_t address, uint16 port, char** targetAlias = NULL);
status_t Close();
uint32 CommandSequenceNumber() const { return fCommandSequenceNumber; }
uint32 NextCommandSequenceNumber() { return fCommandSequenceNumber++; }
iSCSIConnection* Connection() const { return fConnection; }
bool Active() { return fConnection != NULL && fConnection->Active(); }
private:
bool fDiscovery;
const char* fTargetName;
uint32 fCommandSequenceNumber;
iSCSIConnection* fConnection;
// XXX should allow for multiple
};
class iSCSITarget : public Node {
public:
iSCSITarget();
virtual ~iSCSITarget();
status_t Init(ip_addr_t address, uint16 port, const char* targetName);
virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer,
size_t bufferSize);
virtual ssize_t WriteAt(void* cookie, off_t pos, const void* buffer,
size_t bufferSize);
virtual status_t GetName(char* buffer, size_t bufferSize) const;
virtual off_t Size() const;
static bool DiscoverTargets(ip_addr_t address, uint16 port,
NodeList* devicesList);
static bool _AddDevice(ip_addr_t address, uint16 port,
const char* targetName, NodeList* devicesList);
private:
status_t _GetSize();
iSCSISession* fSession;
char* fTargetName;
char* fTargetAlias;
uint32 fLastLBA;
uint32 fBlockSize;
};
#endif