mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-11-17 15:08:08 +00:00
scsi_bus: packet data transfers.
This commit is contained in:
parent
c7ceb9d6b9
commit
fbfae98d6d
@ -144,6 +144,7 @@ public:
|
|||||||
|
|
||||||
// ScsiDevice methods
|
// ScsiDevice methods
|
||||||
void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param);
|
void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param);
|
||||||
|
bool has_data() { return this->data_fifo_pos != 0; };
|
||||||
bool send_bytes(uint8_t* dst_ptr, int count);
|
bool send_bytes(uint8_t* dst_ptr, int count);
|
||||||
void process_command() {};
|
void process_command() {};
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace ScsiPhase {
|
namespace ScsiPhase {
|
||||||
enum : int {
|
enum : int {
|
||||||
BUS_FREE = 0,
|
BUS_FREE = 0,
|
||||||
ARBITRATION,
|
ARBITRATION,
|
||||||
SELECTION,
|
SELECTION,
|
||||||
@ -58,7 +58,7 @@ enum : int {
|
|||||||
MESSAGE_IN,
|
MESSAGE_IN,
|
||||||
MESSAGE_OUT,
|
MESSAGE_OUT,
|
||||||
RESET,
|
RESET,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ScsiMsg : int {
|
enum ScsiMsg : int {
|
||||||
@ -140,6 +140,7 @@ public:
|
|||||||
|
|
||||||
virtual void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param);
|
virtual void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param);
|
||||||
|
|
||||||
|
virtual bool has_data() = 0;
|
||||||
virtual bool send_bytes(uint8_t* dst_ptr, int count) = 0;
|
virtual bool send_bytes(uint8_t* dst_ptr, int count) = 0;
|
||||||
|
|
||||||
virtual void process_command() = 0;
|
virtual void process_command() = 0;
|
||||||
@ -179,6 +180,8 @@ public:
|
|||||||
bool end_selection(int initiator_id, int target_id);
|
bool end_selection(int initiator_id, int target_id);
|
||||||
bool transfer_command(uint8_t* dst_ptr);
|
bool transfer_command(uint8_t* dst_ptr);
|
||||||
void disconnect(int dev_id);
|
void disconnect(int dev_id);
|
||||||
|
bool target_request_data();
|
||||||
|
bool target_pull_data(uint8_t* dst_ptr, int size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void change_bus_phase(int initiator_id);
|
void change_bus_phase(int initiator_id);
|
||||||
|
@ -246,6 +246,31 @@ bool ScsiBus::transfer_command(uint8_t* dst_ptr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScsiBus::target_request_data()
|
||||||
|
{
|
||||||
|
if (this->devices[this->target_id]->has_data()) {
|
||||||
|
this->assert_ctrl_line(target_id, SCSI_CTRL_REQ);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScsiBus::target_pull_data(uint8_t* dst_ptr, int size)
|
||||||
|
{
|
||||||
|
if (dst_ptr == nullptr || !size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// transfer the requested number of bytes from target to initiator
|
||||||
|
if (!this->devices[this->target_id]->send_bytes(dst_ptr, size)) {
|
||||||
|
LOG_F(ERROR, "ScsiBus: error while transferring data from target!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ScsiBus::disconnect(int dev_id)
|
void ScsiBus::disconnect(int dev_id)
|
||||||
{
|
{
|
||||||
this->release_ctrl_lines(dev_id);
|
this->release_ctrl_lines(dev_id);
|
||||||
|
@ -123,6 +123,18 @@ void ScsiHardDisk::process_command() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScsiHardDisk::send_bytes(uint8_t* dst_ptr, int count) {
|
||||||
|
if (dst_ptr == nullptr || !count || count > this->cur_buf_cnt) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(dst_ptr, &this->img_buffer[this->cur_buf_pos], count);
|
||||||
|
this->cur_buf_pos += count;
|
||||||
|
this->cur_buf_cnt -= count;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int ScsiHardDisk::test_unit_ready() {
|
int ScsiHardDisk::test_unit_ready() {
|
||||||
if (img_path.empty() || img_path == " ") {
|
if (img_path.empty() || img_path == " ") {
|
||||||
return ScsiError::DEV_NOT_READY;
|
return ScsiError::DEV_NOT_READY;
|
||||||
@ -204,6 +216,8 @@ void ScsiHardDisk::read(uint32_t lba, uint16_t transfer_len, uint8_t cmd_len) {
|
|||||||
|
|
||||||
this->hdd_img.seekg(device_offset, this->hdd_img.beg);
|
this->hdd_img.seekg(device_offset, this->hdd_img.beg);
|
||||||
this->hdd_img.read(img_buffer, transfer_size);
|
this->hdd_img.read(img_buffer, transfer_size);
|
||||||
|
|
||||||
|
this->cur_buf_cnt = transfer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScsiHardDisk::write(uint32_t lba, uint16_t transfer_len, uint8_t cmd_len) {
|
void ScsiHardDisk::write(uint32_t lba, uint16_t transfer_len, uint8_t cmd_len) {
|
||||||
|
@ -41,7 +41,8 @@ public:
|
|||||||
|
|
||||||
void insert_image(std::string filename);
|
void insert_image(std::string filename);
|
||||||
void process_command();
|
void process_command();
|
||||||
bool send_bytes(uint8_t* dst_ptr, int count) { return true; };
|
bool has_data() { return this->cur_buf_cnt != 0; };
|
||||||
|
bool send_bytes(uint8_t* dst_ptr, int count);
|
||||||
|
|
||||||
int test_unit_ready();
|
int test_unit_ready();
|
||||||
int req_sense(uint16_t alloc_len);
|
int req_sense(uint16_t alloc_len);
|
||||||
@ -57,7 +58,7 @@ public:
|
|||||||
void seek(uint32_t lba);
|
void seek(uint32_t lba);
|
||||||
void rewind();
|
void rewind();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
std::string img_path;
|
std::string img_path;
|
||||||
std::fstream hdd_img;
|
std::fstream hdd_img;
|
||||||
uint64_t img_size;
|
uint64_t img_size;
|
||||||
@ -65,6 +66,10 @@ protected:
|
|||||||
uint64_t file_offset = 0;
|
uint64_t file_offset = 0;
|
||||||
uint8_t status = ScsiError::NO_ERROR;
|
uint8_t status = ScsiError::NO_ERROR;
|
||||||
|
|
||||||
|
// SCSI transfer pointers
|
||||||
|
uint32_t cur_buf_pos = 0;
|
||||||
|
uint32_t cur_buf_cnt = 0;
|
||||||
|
|
||||||
//inquiry info
|
//inquiry info
|
||||||
char vendor_info[8] = {'D', 'i', 'n', 'g', 'u', 's', 'D', '\0'};
|
char vendor_info[8] = {'D', 'i', 'n', 'g', 'u', 's', 'D', '\0'};
|
||||||
char prod_info[16] = {'E', 'm', 'u', 'l', 'a', 't', 'e', 'd', ' ', 'D', 'i', 's', 'k', '\0'};
|
char prod_info[16] = {'E', 'm', 'u', 'l', 'a', 't', 'e', 'd', ' ', 'D', 'i', 's', 'k', '\0'};
|
||||||
|
Loading…
Reference in New Issue
Block a user