Started implementing save/restore support for SCSI requests

- save function implemented using a dummy parameter that only receives the
  result of the save operation. The parameter's save/restore handlers doing
  the main job. The numerical values of the requests are saved in a separate
  text file. The data transfer buffers are saved as binary files.
- the request data buffers are now created dynamicly
- TODO: restore SCSI requests
This commit is contained in:
Volker Ruppert 2014-01-28 20:29:12 +00:00
parent d990911cea
commit c217470150
2 changed files with 86 additions and 5 deletions

View File

@ -45,6 +45,37 @@
static SCSIRequest *free_requests = NULL;
static Bit32u serial_number = 12345678;
Bit64s scsireq_save_handler(void *class_ptr, bx_param_c *param)
{
char fname[BX_PATHNAME_LEN];
char path[BX_PATHNAME_LEN];
param->get_param_path(fname, BX_PATHNAME_LEN);
if (!strncmp(fname, "bochs.", 6)) {
strcpy(fname, fname+6);
}
if (SIM->get_param_string(BXPN_RESTORE_PATH)->isempty()) {
return 0;
}
sprintf(path, "%s/%s", SIM->get_param_string(BXPN_RESTORE_PATH)->getptr(), fname);
return ((scsi_device_t*)class_ptr)->save_requests(path);
}
void scsireq_restore_handler(void *class_ptr, bx_param_c *param, Bit64s value)
{
char fname[BX_PATHNAME_LEN];
char path[BX_PATHNAME_LEN];
if (value != 0) {
param->get_param_path(fname, BX_PATHNAME_LEN);
if (!strncmp(fname, "bochs.", 6)) {
strcpy(fname, fname+6);
}
sprintf(path, "%s/%s", SIM->get_param_string(BXPN_RESTORE_PATH)->getptr(), fname);
((scsi_device_t*)class_ptr)->restore_requests(path);
}
}
scsi_device_t::scsi_device_t(device_image_t *_hdimage, int _tcq,
scsi_completionfn _completion, void *_dev)
{
@ -97,6 +128,7 @@ scsi_device_t::~scsi_device_t(void)
r = requests;
while (r != NULL) {
next = r->next;
delete [] r->dma_buf;
delete r;
r = next;
}
@ -105,6 +137,7 @@ scsi_device_t::~scsi_device_t(void)
r = free_requests;
while (r != NULL) {
next = r->next;
delete [] r->dma_buf;
delete r;
r = next;
}
@ -118,9 +151,12 @@ void scsi_device_t::register_state(bx_list_c *parent, const char *name)
{
bx_list_c *list = new bx_list_c(parent, name, "");
new bx_shadow_num_c(list, "sense", &sense);
// TODO: save/restore for SCSI requests
bx_param_bool_c *requests = new bx_param_bool_c(list, "requests", NULL, NULL, 0);
requests->set_sr_handlers(this, scsireq_save_handler, scsireq_restore_handler);
}
// SCSI request handling
SCSIRequest* scsi_device_t::scsi_new_request(Bit32u tag)
{
SCSIRequest *r;
@ -130,8 +166,8 @@ SCSIRequest* scsi_device_t::scsi_new_request(Bit32u tag)
free_requests = r->next;
} else {
r = new SCSIRequest;
r->dma_buf = new Bit8u[SCSI_DMA_BUF_SIZE];
}
r->dev = this;
r->tag = tag;
r->sector_count = 0;
r->buf_len = 0;
@ -178,6 +214,51 @@ SCSIRequest* scsi_device_t::scsi_find_request(Bit32u tag)
return r;
}
bx_bool scsi_device_t::save_requests(const char *path)
{
char tmppath[BX_PATHNAME_LEN];
if (requests != NULL) {
FILE *fp1 = fopen(path, "w");
if (fp1 != NULL) {
SCSIRequest *r = requests;
Bit32u i = 0;
while (r != NULL) {
fprintf(fp1, "%u = {\n", i);
fprintf(fp1, " tag = %u\n", r->tag);
fprintf(fp1, " sector = "FMT_LL"u\n", r->sector);
fprintf(fp1, " sector_count = %u\n", r->sector_count);
fprintf(fp1, " buf_len = %d\n", r->buf_len);
fprintf(fp1, " status = %u\n", r->status);
fprintf(fp1, "}\n");
if (r->buf_len > 0) {
sprintf(tmppath, "%s.%u", path, i);
FILE *fp2 = fopen(tmppath, "wb");
if (fp2 != NULL) {
fwrite(r->dma_buf, 1, (size_t)r->buf_len, fp2);
}
fclose(fp2);
}
r = r->next;
i++;
}
fclose(fp1);
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
void scsi_device_t::restore_requests(const char *path)
{
// TODO: restore SCSI requests
}
// SCSI command implementation
void scsi_device_t::scsi_command_complete(SCSIRequest *r, int status, int _sense)
{
Bit32u tag;

View File

@ -30,7 +30,6 @@
typedef void (*scsi_completionfn)(void *opaque, int reason, Bit32u tag,
Bit32u arg);
class scsi_device_t;
class cdrom_base_c;
enum scsidev_type {
@ -56,12 +55,11 @@ enum scsi_reason {
#define SCSI_MAX_INQUIRY_LEN 256
typedef struct SCSIRequest {
scsi_device_t *dev;
Bit32u tag;
Bit64u sector;
Bit32u sector_count;
int buf_len;
Bit8u dma_buf[SCSI_DMA_BUF_SIZE];
Bit8u *dma_buf;
Bit32u status;
struct SCSIRequest *next;
} SCSIRequest;
@ -89,6 +87,8 @@ public:
bx_bool get_inserted() {return inserted;}
static void seek_timer_handler(void *);
void seek_timer(void);
bx_bool save_requests(const char *path);
void restore_requests(const char *path);
protected:
SCSIRequest* scsi_new_request(Bit32u tag);