]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Automatically increase scsi buffer size when needed.
authorToni Wilen <twilen@winuae.net>
Wed, 27 Aug 2014 18:04:46 +0000 (21:04 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 27 Aug 2014 18:04:46 +0000 (21:04 +0300)
blkdev.cpp
include/scsi.h
scsi.cpp

index 1a6b884df22e665d8f671d4b461f436945c34511..7bc46e1bee040a07799285b2f37995763ba8fc97 100644 (file)
@@ -1223,7 +1223,7 @@ static int scsi_read_cd_data (int unitnum, uae_u8 *scsi_data, uae_u32 offset, ua
                *scsi_len = 0;
                return 0;
        } else {
-               if (len * di->bytespersector > SCSI_DATA_BUFFER_SIZE)
+               if (len * di->bytespersector > SCSI_DEFAULT_DATA_BUFFER_SIZE)
                        return -3;
                if (offset >= di->sectorspertrack * di->cylinders * di->trackspercylinder)
                        return -1;
@@ -1261,7 +1261,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
        sys_command_info (unitnum, &di, 1);
 
        if (log_scsiemu) {
-               write_log (_T("SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%p LEN=%d\n"), unitnum,
+               write_log (_T("SCSIEMU CD %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%p LEN=%d\n"), unitnum,
                        cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6], 
                        cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11],
                        scsi_cmd_len, scsi_data, dlen);
index 1914a02713296050d2789875a1219f64c78d6c44..bb96a165052290321e006fcd2c7ed8db5af2fe7f 100644 (file)
@@ -1,5 +1,5 @@
 
-#define SCSI_DATA_BUFFER_SIZE (512 * 512)
+#define SCSI_DEFAULT_DATA_BUFFER_SIZE (256 * 512)
 
 struct scsi_data_tape
 {
@@ -36,7 +36,8 @@ struct scsi_data
        int blocksize;
 
     int offset;
-    uae_u8 buffer[SCSI_DATA_BUFFER_SIZE];
+    uae_u8 *buffer;
+       int buffer_size;
     struct hd_hardfiledata *hfd;
        struct scsi_data_tape *tape;
     int device_type;
@@ -110,3 +111,29 @@ extern void tape_media_change (int unitnum, struct uaedev_config_info*);
 #define SCSI_STATUS_COMMAND_TERMINATED     0x22
 #define SCSI_STATUS_QUEUE_FULL             0x28
 #define SCSI_STATUS_ACA_ACTIVE             0x30
+
+#define SCSI_MEMORY_FUNCTIONS(x, y, z) \
+static void REGPARAM2 x ## _bput(uaecptr addr, uae_u32 b) \
+{ \
+       y ## _bput(& ## z, addr, b); \
+} \
+static void REGPARAM2 x ## _wput(uaecptr addr, uae_u32 b) \
+{ \
+       y ## _wput(& ## z, addr, b); \
+} \
+static void REGPARAM2 x ## _lput(uaecptr addr, uae_u32 b) \
+{ \
+       y ## _lput(& ## z, addr, b); \
+} \
+static uae_u32 REGPARAM2 x ## _bget(uaecptr addr) \
+{ \
+return y ## _bget(& ## z, addr); \
+} \
+static uae_u32 REGPARAM2 x ## _wget(uaecptr addr) \
+{ \
+return y ## _wget(& ## z, addr); \
+} \
+static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \
+{ \
+return y ## _lget(& ## z, addr); \
+}
index 60b835f39aa758ea2256f15687a6b39f3cd1d2cb..32199c868d00299fa11e6091de16c6c2e812ec0a 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
 #include "blkdev.h"
 #include "zfile.h"
 
-static int outcmd[] = { 0x0a, 0x2a, 0xaa, 0x15, 0x55, -1 };
-static int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 };
-static int nonecmd[] = { 0x00, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, -1 };
-static int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 };
+#define SCSI_EMU_DEBUG 0
+
+static const int outcmd[] = { 0x0a, 0x2a, 0xaa, 0x15, 0x55, -1 };
+static const int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 };
+static const int nonecmd[] = { 0x00, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, -1 };
+static const int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 };
+
+static void scsi_grow_buffer(struct scsi_data *sd, int newsize)
+{
+       if (sd->buffer_size >= newsize)
+               return;
+       uae_u8 *oldbuf = sd->buffer;
+       int oldsize = sd->buffer_size;
+       sd->buffer_size = newsize + SCSI_DEFAULT_DATA_BUFFER_SIZE;
+       write_log(_T("SCSI buffer %d -> %d\n"), oldsize, sd->buffer_size);
+       sd->buffer = xmalloc(uae_u8, sd->buffer_size);
+       memcpy(sd->buffer, oldbuf, oldsize);
+       xfree(oldbuf);
+}
 
 static int scsi_data_dir(struct scsi_data *sd)
 {
@@ -48,25 +63,42 @@ static int scsi_data_dir(struct scsi_data *sd)
 
 void scsi_emulate_analyze (struct scsi_data *sd)
 {
-       int cmd_len, data_len;
+       int cmd_len, data_len, data_len2;
 
        data_len = sd->data_len;
+       data_len2 = 0;
        cmd_len = scsicmdsizes[sd->cmd[0] >> 5];
        sd->cmd_len = cmd_len;
        switch (sd->cmd[0])
        {
+       case 0x08:
+               data_len2 = sd->cmd[4] * sd->blocksize;
+               scsi_grow_buffer(sd, data_len2);
+       break;
+       case 0x28:
+               data_len2 = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->blocksize;
+               scsi_grow_buffer(sd, data_len2);
+       break;
+       case 0xa8:
+               data_len2 = ((sd->cmd[6] << 24) | (sd->cmd[7] << 16) | (sd->cmd[8] << 8) | (sd->cmd[9] << 0)) * (uae_s64)sd->blocksize;
+               scsi_grow_buffer(sd, data_len2);
+       break;
        case 0x0a:
                data_len = sd->cmd[4] * sd->blocksize;
+               scsi_grow_buffer(sd, data_len);
        break;
        case 0x2a:
                data_len = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->blocksize;
+               scsi_grow_buffer(sd, data_len);
        break;
        case 0xaa:
                data_len = ((sd->cmd[6] << 24) | (sd->cmd[7] << 16) | (sd->cmd[8] << 8) | (sd->cmd[9] << 0)) * (uae_s64)sd->blocksize;
+               scsi_grow_buffer(sd, data_len);
        break;
        case 0x2f: // VERIFY
                if (sd->cmd[1] & 2) {
                        sd->data_len = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->blocksize;
+                       scsi_grow_buffer(sd, sd->data_len);
                        sd->direction = 1;
                } else {
                        sd->data_len = 0;
@@ -111,7 +143,9 @@ static void showsense(struct scsi_data *sd)
 static void copysense(struct scsi_data *sd)
 {
        int len = sd->cmd[4];
-       //write_log (_T("REQUEST SENSE length %d (%d)\n"), len, sd->sense_len);
+#if SCSI_EMU_DEBUG
+       write_log (_T("REQUEST SENSE length %d (%d)\n"), len, sd->sense_len);
+#endif
        memset(sd->buffer, 0, len);
        memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
        if (sd->sense_len == 0)
@@ -139,7 +173,10 @@ void scsi_emulate_cmd(struct scsi_data *sd)
                sd->cmd[1] &= ~(7 << 5);
                sd->cmd[1] |= lun << 5;
        }
-       //write_log (_T("CMD=%02x\n"), sd->cmd[0]);
+#if SCSI_EMU_DEBUG
+       write_log (_T("CMD=%02x.%02x.%02x.%02x.%02x.%02x (%d,%d)\n"),
+               sd->cmd[0], sd->cmd[1], sd->cmd[2], sd->cmd[3], sd->cmd[4], sd->cmd[5], sd->device_type, sd->nativescsiunit);
+#endif
        if (sd->device_type == UAEDEV_CD && sd->cd_emu_unit >= 0) {
                if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
                        scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, 0, 0, 0, 0, 0, 0, 0, sd->atapi); /* ack request sense */
@@ -193,6 +230,12 @@ void scsi_emulate_cmd(struct scsi_data *sd)
        sd->offset = 0;
 }
 
+static void allocscsibuf(struct scsi_data *sd)
+{
+       sd->buffer_size = SCSI_DEFAULT_DATA_BUFFER_SIZE;
+       sd->buffer = xcalloc(uae_u8, sd->buffer_size);
+}
+
 struct scsi_data *scsi_alloc_hd(int id, struct hd_hardfiledata *hfd)
 {
        struct scsi_data *sd = xcalloc (struct scsi_data, 1);
@@ -202,6 +245,7 @@ struct scsi_data *scsi_alloc_hd(int id, struct hd_hardfiledata *hfd)
        sd->cd_emu_unit = -1;
        sd->blocksize = hfd->hfd.ci.blocksize;
        sd->device_type = UAEDEV_HDF;
+       allocscsibuf(sd);
        return sd;
 }
 
@@ -219,6 +263,7 @@ struct scsi_data *scsi_alloc_cd(int id, int unitnum, bool atapi)
        sd->atapi = atapi;
        sd->blocksize = 2048;
        sd->device_type = UAEDEV_CD;
+       allocscsibuf(sd);
        return sd;
 }
 
@@ -235,6 +280,7 @@ struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool read
        sd->blocksize = tape->blocksize;
        sd->tape = tape;
        sd->device_type = UAEDEV_TAPE;
+       allocscsibuf(sd);
        return sd;
 }
 
@@ -251,6 +297,7 @@ struct scsi_data *scsi_alloc_native(int id, int nativeunit)
        sd->cd_emu_unit = -1;
        sd->blocksize = 2048;
        sd->device_type = 0;
+       allocscsibuf(sd);
        return sd;
 }
 
@@ -272,6 +319,7 @@ void scsi_free(struct scsi_data *sd)
                sd->cd_emu_unit = -1;
        }
        tape_free (sd->tape);
+       xfree(sd->buffer);
        xfree(sd);
 }
 
@@ -283,7 +331,7 @@ void scsi_start_transfer(struct scsi_data *sd)
 int scsi_send_data(struct scsi_data *sd, uae_u8 b)
 {
        if (sd->direction == 1) {
-               if (sd->offset >= SCSI_DATA_BUFFER_SIZE) {
+               if (sd->offset >= sd->buffer_size) {
                        write_log (_T("SCSI data buffer overflow!\n"));
                        return 0;
                }