From 7206af2a752fa67e367b34bde46480326b924f5c Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 17 Nov 2005 06:44:44 +0000 Subject: [PATCH] SCSI interface --- libscsi/Makefile | 17 +++++++++ libscsi/libscsi.h | 15 ++++++++ libscsi/scsi_INQUIRY.c | 36 +++++++++++++++++++ libscsi/scsi_READ.c | 67 ++++++++++++++++++++++++++++++++++++ libscsi/scsi_READ_CAPACITY.c | 36 +++++++++++++++++++ libscsi/scsi_command.c | 62 +++++++++++++++++++++++++++++++++ libscsi/scsi_read_sector.c | 30 ++++++++++++++++ 7 files changed, 263 insertions(+) create mode 100644 libscsi/Makefile create mode 100644 libscsi/libscsi.h create mode 100644 libscsi/scsi_INQUIRY.c create mode 100644 libscsi/scsi_READ.c create mode 100644 libscsi/scsi_READ_CAPACITY.c create mode 100644 libscsi/scsi_command.c create mode 100644 libscsi/scsi_read_sector.c diff --git a/libscsi/Makefile b/libscsi/Makefile new file mode 100644 index 0000000..b539198 --- /dev/null +++ b/libscsi/Makefile @@ -0,0 +1,17 @@ +# +# (c) 2005 Laurent Vivier +# + +TOP=$(shell pwd) +CFLAGS = -nostdlib -nodefaultlibs -Wall -Werror -Wno-multichar -fpic -O2 +CPPFLAGS = -I$(TOP)/../libmacos -DARCH_M68K + +LIBRARY = libscsi.a + +SOURCES = scsi_read_sector.c scsi_command.c scsi_INQUIRY.c scsi_READ.c + +HEADERS = libscsi.h + +all: $(LIBRARY) + +include $(TOP)/../Rules.mk diff --git a/libscsi/libscsi.h b/libscsi/libscsi.h new file mode 100644 index 0000000..3beab7e --- /dev/null +++ b/libscsi/libscsi.h @@ -0,0 +1,15 @@ +/* + * + * (c) 2004, 2005 Laurent Vivier + * + */ + +#include +#include + +extern int scsi_command(int target, char* cdb, int count, TIB_t* tib); +extern int scsi_INQUIRY(int target, char* buffer, size_t count); +extern int scsi_READ(int target, unsigned long offset, unsigned short nb_blocks, + char *buffer, int buffer_size); + +extern int scsi_read_sector(off_t offset, void* buffer, size_t size); diff --git a/libscsi/scsi_INQUIRY.c b/libscsi/scsi_INQUIRY.c new file mode 100644 index 0000000..5fbf1e6 --- /dev/null +++ b/libscsi/scsi_INQUIRY.c @@ -0,0 +1,36 @@ +/* + * + * (c) 2004, 2005 Laurent Vivier + * + */ + +#include + +#include + +#include +#include + +#include "libscsi.h" + +int scsi_INQUIRY(int target, char *buffer, size_t count) +{ + char cdb[6]; + TIB_t tib[2]; + + cdb[0] = INQUIRY; + cdb[1] = 0; + cdb[2] = 0; + cdb[3] = 0; + cdb[4] = count; + cdb[5] = 0; + + tib[0].opcode = op_no_inc; + tib[0].param1 = (int)buffer; + tib[0].param2 = count; + tib[1].opcode = op_stop; + tib[1].param1 = 0; + tib[1].param2 = 0; + + return scsi_command(target, cdb, 6, tib); +} diff --git a/libscsi/scsi_READ.c b/libscsi/scsi_READ.c new file mode 100644 index 0000000..a77037d --- /dev/null +++ b/libscsi/scsi_READ.c @@ -0,0 +1,67 @@ +/* + * + * (c) 2004, 2005 Laurent Vivier + * + */ + +#include +#include + +#include +#include + +#include "libscsi.h" + +/****************************************************************************** ++=====-========-========-========-========-========-========-========-========+ +| Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +|Byte | | | | | | | | | +|=====+=======================================================================| +| 0 | Operation code (28h) | +|-----+-----------------------------------------------------------------------| +| 1 | Logical unit number | DPO | FUA | Reserved | RelAdr | +|-----+-----------------------------------------------------------------------| +| 2 | (MSB) | +|-----+--- ---| +| 3 | | +|-----+--- Logical block address ---| +| 4 | | +|-----+--- ---| +| 5 | (LSB) | +|-----+-----------------------------------------------------------------------| +| 6 | Reserved | +|-----+-----------------------------------------------------------------------| +| 7 | (MSB) | +|-----+--- Transfer length | +| 8 | (LSB) | +|-----+-----------------------------------------------------------------------| +| 9 | Control | ++=============================================================================+ +******************************************************************************/ + +int scsi_READ(int target, unsigned long offset, unsigned short nb_blocks, + char *buffer, int buffer_size) +{ + char cdb[10]; + TIB_t tib[2]; + + cdb[0] = READ_10; + cdb[1] = 0; + cdb[2] = (offset >> 24) & 0xFF; + cdb[3] = (offset >> 16) & 0xFF; + cdb[4] = (offset >> 8) & 0xFF; + cdb[5] = offset & 0xFF; + cdb[6] = 0; + cdb[7] = (nb_blocks >> 8) & 0xFF; + cdb[8] = nb_blocks & 0xFF; + cdb[9] = 0; + + tib[0].opcode = op_no_inc; + tib[0].param1 = (int)buffer; + tib[0].param2 = buffer_size; + tib[1].opcode = op_stop; + tib[1].param1 = 0; + tib[1].param2 = 0; + + return scsi_command(target, cdb, 10, tib); +} diff --git a/libscsi/scsi_READ_CAPACITY.c b/libscsi/scsi_READ_CAPACITY.c new file mode 100644 index 0000000..0b3c30d --- /dev/null +++ b/libscsi/scsi_READ_CAPACITY.c @@ -0,0 +1,36 @@ +/* + * + * (c) 2004, 2005 Laurent Vivier + * + */ + +#include + +#include +#include + +#include "libscsi.h" + +int scsi_INQUIRY(int target, char *buffer, size_t count) +{ + char cdb[8]; + TIB_t tib[2]; + + cdb[0] = READ_CAPACITY; + cdb[1] = 0; + cdb[2] = 0; + cdb[3] = 0; + cdb[4] = 0; + cdb[5] = 0; + cdb[6] = 0; + cdb[7] = 0; + + tib[0].opcode = op_no_inc; + tib[0].param1 = (int)buffer; + tib[0].param2 = count; + tib[1].opcode = op_stop; + tib[1].param1 = 0; + tib[1].param2 = 0; + + return scsi_command(target, cdb, 6, tib); +} diff --git a/libscsi/scsi_command.c b/libscsi/scsi_command.c new file mode 100644 index 0000000..3504d68 --- /dev/null +++ b/libscsi/scsi_command.c @@ -0,0 +1,62 @@ +/* + * + * (c) 2004, 2005 Laurent Vivier + * + */ + +#include + +#include + +#include +#include + +#include "libscsi.h" + +#define COMPLETION_TIMEOUT 300 + +int scsi_command(int target, char* cdb, int count, TIB_t* tib) +{ + int err; + short stat; + short message; + + err = SCSIGet(); + if (err != noErr) + { + printf("Cannot get SCSI bus (%d)\n", err); + return err; + } + + err = SCSISelect(target); + if (err != noErr) + { + printf("Cannot select target %d (%d)\n", target, err); + return err; + } + + err = SCSICmd(cdb, count); + if (err != noErr) + { + printf("Cannot send command (%d)\n", err); + goto complete; + } + + err = SCSIRead(tib); + if (err != noErr) + { + printf("Cannot read data (%d)\n", err); + goto complete; + } + +complete: + err = SCSIComplete(&stat, &message, COMPLETION_TIMEOUT); + if (err != noErr) + { + printf("Cannot complete transaction %d %d(%d)\n", + stat, message, err); + return err; + } + + return noErr; +} diff --git a/libscsi/scsi_read_sector.c b/libscsi/scsi_read_sector.c new file mode 100644 index 0000000..b9cae40 --- /dev/null +++ b/libscsi/scsi_read_sector.c @@ -0,0 +1,30 @@ +/* + * + * (c) 2004, 2005 Laurent Vivier + * + */ + +#include +#include + +#include + +#include "libscsi.h" + +#define SECTOR_SIZE (2048) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +/* offset is a block number + * size is the number of bytes to read + */ + +int scsi_read_sector(off_t offset, void* buffer, size_t size) +{ + OSErr err; + + err = scsi_READ(3, offset, ISO_BLOCKS(size), buffer, size); + if (err != noErr) + return -1; + + return 0; +}