Almost identical to USBHostShell; reads all endpoint descriptors

Dependents:   myBlueUSB mbed_TANK_Kinect myBlueUSB_ros myBlueUSB_localfix

Files at this revision

API Documentation at this revision

Comitter:
networker
Date:
Fri Jul 01 09:13:39 2011 +0000
Parent:
2:74fd0a8f9d02
Commit message:
revised massStorage to cope with different endpoint addresses

Changed in this revision

MassStorage.cpp Show annotated file Show diff for this revision Revisions of this file
MassStorage.h Show annotated file Show diff for this revision Revisions of this file
--- a/MassStorage.cpp	Sun May 08 18:01:11 2011 +0000
+++ b/MassStorage.cpp	Fri Jul 01 09:13:39 2011 +0000
@@ -25,45 +25,12 @@
 #include "stdio.h"
 #include "string.h"
 
-#include "Utils.h"
-#include "USBHost.h"
-
-
-int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize);
-int MassStorage_ReadBlock(int device, u32 block, u8* dst);
-int MassStorage_WriteBlock(int device, u32 block, const u8* dst);
-
-
-#define ERR_BAD_CSW_SIGNATURE -200
-
-#define CBW_SIGNATURE  0x43425355
-#define CSW_SIGNATURE  0x53425355
+#include "MassStorage.h"
 
-//  Command Block
-typedef struct
-{
-    u32 Signature;
-    u32 Tag;
-    u32 TransferLength;
-    u8 Flags;
-    u8 LUN;
-    u8 CBLength;
-    u8 CB[16];   // only 6 really
-} CBW;
-
-//  Status block
-typedef struct
-{
-    u32 Signature;
-    u32 Tag;
-    u32 DataResidue;
-    u8 Status;
-} CSW;
-
+#if 0
 int SCSIRequestSense(int device);
 
-int DoSCSI(int device, const u8* cmd, int cmdLen, int flags, u8* data, u32 transferLen)
-{
+int DoSCSI(int device, const u8* cmd, int cmdLen, int flags, u8* data, u32 transferLen) {
     CBW cbw;
     cbw.Signature = CBW_SIGNATURE;
     cbw.Tag = 0;
@@ -75,23 +42,29 @@
     memcpy(cbw.CB,cmd,cmdLen);
 
     int r;
-    r = USBBulkTransfer(device,0x01,(u8*)&cbw,31);   // Send the command
-    if (r < 0)
+    //r = USBBulkTransfer(device,0x01,(u8*)&cbw,31);   // Send the command
+    r = USBBulkTransfer(device,BULK_ENDPOINT_OUT,(u8*)&cbw,31);   // Send the command
+    if (r < 0) {
+        printf("first transfer returns %d\n", r);
         return r;
-
-    if (data)
-    {
-        r = USBBulkTransfer(device,flags | 1,data,transferLen);
-        if (r < 0)
+    }
+    if (data) {
+        //r = USBBulkTransfer(device,flags | 1,data,transferLen);
+        r = USBBulkTransfer(device,flags ? BULK_ENDPOINT_IN : BULK_ENDPOINT_OUT,data,transferLen);
+        if (r < 0) {
+            printf("second transfer returns %d (flags=%02xH)\n", r, flags);
             return r;
+        }
     }
 
     CSW csw;
     csw.Signature = 0;
-    r = USBBulkTransfer(device,0x81,(u8*)&csw,13);
-    if (r < 0)
+    //r = USBBulkTransfer(device,0x81,(u8*)&csw,13);
+    r = USBBulkTransfer(device,BULK_ENDPOINT_IN,(u8*)&csw,13);
+    if (r < 0) {
+        printf("third transfer returns %d\n", r);
         return r;
-
+    }
     if (csw.Signature != CSW_SIGNATURE)
         return ERR_BAD_CSW_SIGNATURE;
 
@@ -102,23 +75,20 @@
     return csw.Status;
 }
 
-int SCSITestUnitReady(int device)
-{
+int SCSITestUnitReady(int device) {
     u8 cmd[6];
     memset(cmd,0,6);
     return DoSCSI(device,cmd,6,DEVICE_TO_HOST,0,0);
 }
 
-int SCSIRequestSense(int device)
-{
+int SCSIRequestSense(int device) {
     u8 cmd[6] = {0x03,0,0,0,18,0};
     u8 result[18];
     int r = DoSCSI(device,cmd,6,DEVICE_TO_HOST,result,18);
     return r;
 }
 
-int SCSIInquiry(int device)
-{
+int SCSIInquiry(int device) {
     u8 cmd[6] = {0x12,0,0,0,36,0};
     u8 result[36+2];
     result[36] = '\n';
@@ -129,26 +99,22 @@
     return r;
 }
 
-int SCSIReadCapacity(int device, u32* blockCount, u32* blockSize)
-{
+int SCSIReadCapacity(int device, u32* blockCount, u32* blockSize) {
     u8 cmd[10] = {0x25,0,0,0,8,0,0,0,0,0};
     u8 result[8];
     *blockSize = 0;
     *blockCount = 0;
     int r = DoSCSI(device,cmd,10,DEVICE_TO_HOST,result,8);
-    if (r == 0)
-    {
+    if (r == 0) {
         *blockCount = BE32(result);
         *blockSize = BE32(result+4);
     }
     return r;
 }
 
-int SCSITransfer(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize, int direction)
-{
+int SCSITransfer(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize, int direction) {
     //  USB hardware will only do 4k per transfer
-    while (blockCount*blockSize > 4096)
-    {
+    while (blockCount*blockSize > 4096) {
         int count = 4096/blockSize;
         int r = SCSITransfer(device,blockAddr,count,dst,blockSize,direction);
         dst += count*blockSize;
@@ -164,17 +130,21 @@
     return DoSCSI(device,cmd,10,direction,dst,blockSize*blockCount);
 }
 
-int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize)
-{
-    return SCSIReadCapacity(device,blockCount,blockSize);
+int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize) {
+    int result = SCSIReadCapacity(device,blockCount,blockSize);
+    printf("MSReadCapacity(%d) = %d, blocks=%u, blksiz=%u\n", device, result, *blockCount, *blockSize);
+    return result;
 }
 
-int MassStorage_Read(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize = 512)
-{
-    return SCSITransfer(device,blockAddr,blockCount,dst,blockSize,DEVICE_TO_HOST);
+int MassStorage_Read(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize = 512) {
+    int result = SCSITransfer(device,blockAddr,blockCount,dst,blockSize,DEVICE_TO_HOST);
+    printf("MSRead(%d, %u, %u, %p, %d) = %d\n", device, blockAddr, blockCount, dst, blockSize, result);
+    return result;
 }
 
-int MassStorage_Write(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize = 512)
-{
-    return SCSITransfer(device,blockAddr,blockCount,dst,blockSize,HOST_TO_DEVICE);
+int MassStorage_Write(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize = 512) {
+    int result  = SCSITransfer(device,blockAddr,blockCount,dst,blockSize,HOST_TO_DEVICE);
+    printf("MSWrite(%d, %u, %u, %p, %d) = %d\n", device, blockAddr, blockCount, dst, blockSize, result);
+    return result;
 }
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MassStorage.h	Fri Jul 01 09:13:39 2011 +0000
@@ -0,0 +1,149 @@
+#ifndef MASSSTORAGE_H
+#define MASSSTORAGE_H
+
+#include "Utils.h"
+#include "USBHost.h"
+
+
+#define ERR_BAD_CSW_SIGNATURE -200
+
+#define CBW_SIGNATURE  0x43425355
+#define CSW_SIGNATURE  0x53425355
+
+#define BULK_ENDPOINT_IN    0x81
+#define BULK_ENDPOINT_OUT   0x02
+
+//  Command Block
+typedef struct {
+    u32 Signature;
+    u32 Tag;
+    u32 TransferLength;
+    u8 Flags;
+    u8 LUN;
+    u8 CBLength;
+    u8 CB[16];   // only 6 really
+} CBW;
+
+//  Status block
+typedef struct {
+    u32 Signature;
+    u32 Tag;
+    u32 DataResidue;
+    u8 Status;
+} CSW;
+
+class USBSCSI {
+protected:
+    int _device;
+    unsigned char epin, epout;
+public:
+    USBSCSI() : _device(0) {}
+
+    void SetDevice(int device, unsigned char in, unsigned char out)
+    {
+        _device = device;
+        epin = in;
+        epout = out;
+    }
+protected:    
+    int DoSCSI(const u8* cmd, int cmdLen, int flags, u8* data, u32 transferLen) {
+        CBW cbw;
+        cbw.Signature = CBW_SIGNATURE;
+        cbw.Tag = 0;
+        cbw.TransferLength = transferLen;
+        cbw.Flags = flags;
+        cbw.LUN = 0;
+        cbw.CBLength = cmdLen;
+        memset(cbw.CB,0,sizeof(cbw.CB));
+        memcpy(cbw.CB,cmd,cmdLen);
+
+        int r;
+        //r = USBBulkTransfer(device,0x01,(u8*)&cbw,31);   // Send the command
+        r = USBBulkTransfer(_device,epout,(u8*)&cbw,31);   // Send the command
+        if (r < 0) {
+            printf("first transfer returns %d\n", r);
+            return r;
+        }
+        if (data) {
+            //r = USBBulkTransfer(device,flags | 1,data,transferLen);
+            r = USBBulkTransfer(_device,flags ? epin : epout,data,transferLen);
+            if (r < 0) {
+                printf("second transfer returns %d (flags=%02xH)\n", r, flags);
+                return r;
+            }
+        }
+
+        CSW csw;
+        csw.Signature = 0;
+        //r = USBBulkTransfer(device,0x81,(u8*)&csw,13);
+        r = USBBulkTransfer(_device,epin,(u8*)&csw,13);
+        if (r < 0) {
+            printf("third transfer returns %d\n", r);
+            return r;
+        }
+        if (csw.Signature != CSW_SIGNATURE)
+            return ERR_BAD_CSW_SIGNATURE;
+
+        // ModeSense?
+        if (csw.Status == 1 && cmd[0] != 3)
+            return SCSIRequestSense();
+
+        return csw.Status;
+    }
+
+    int SCSITestUnitReady() {
+        u8 cmd[6];
+        memset(cmd,0,6);
+        return DoSCSI(cmd,6,DEVICE_TO_HOST,0,0);
+    }
+
+    int SCSIRequestSense() {
+        u8 cmd[6] = {0x03,0,0,0,18,0};
+        u8 result[18];
+        int r = DoSCSI(cmd,6,DEVICE_TO_HOST,result,18);
+        return r;
+    }
+
+    int SCSIInquiry() {
+        u8 cmd[6] = {0x12,0,0,0,36,0};
+        u8 result[36+2];
+        result[36] = '\n';
+        result[37] = 0;
+        int r = DoSCSI(cmd,6,DEVICE_TO_HOST,result,36);
+        if (r == 0)
+            printf((const char*)result + 8);
+        return r;
+    }
+
+    int SCSIReadCapacity(u32* blockCount, u32* blockSize) {
+        u8 cmd[10] = {0x25,0,0,0,8,0,0,0,0,0};
+        u8 result[8];
+        *blockSize = 0;
+        *blockCount = 0;
+        int r = DoSCSI(cmd,10,DEVICE_TO_HOST,result,8);
+        if (r == 0) {
+            *blockCount = BE32(result);
+            *blockSize = BE32(result+4);
+        }
+        return r;
+    }
+
+    int SCSITransfer(u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize, int direction) {
+        //  USB hardware will only do 4k per transfer
+        while (blockCount*blockSize > 4096) {
+            int count = 4096/blockSize;
+            int r = SCSITransfer(blockAddr,count,dst,blockSize,direction);
+            dst += count*blockSize;
+            blockAddr += count;
+            blockCount -= count;
+        }
+
+        u8 cmd[10];
+        memset(cmd,0,10);
+        cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
+        BE32(blockAddr,cmd+2);
+        BE16(blockCount,cmd+7);
+        return DoSCSI(cmd,10,direction,dst,blockSize*blockCount);
+    }
+};
+#endif
\ No newline at end of file