mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-27 01:29:29 +00:00
- scsi_linux.cpp uses SCSI generic interface version 2
- slightly more verbose SCSI debugging messages
This commit is contained in:
parent
0662d7a1f1
commit
d6d7976939
|
@ -41,7 +41,6 @@ Unix:
|
||||||
- clip_unix.cpp: use X selections instead of cut buffer
|
- clip_unix.cpp: use X selections instead of cut buffer
|
||||||
- sys_unix.cpp: SysFormat(), SysIsFixedDisk(), SysIsDiskInserted(),
|
- sys_unix.cpp: SysFormat(), SysIsFixedDisk(), SysIsDiskInserted(),
|
||||||
prevent/allow for non-floppy/CDROM devices
|
prevent/allow for non-floppy/CDROM devices
|
||||||
- scsi_linux.cpp: adapt to SCSI Generic driver V2.0
|
|
||||||
- ESD is also available on Solaris
|
- ESD is also available on Solaris
|
||||||
- serial_unix.cpp: provide a way to pipe input/output to programs
|
- serial_unix.cpp: provide a way to pipe input/output to programs
|
||||||
- display progress bar during disk file creation in prefs editor
|
- display progress bar during disk file creation in prefs editor
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define DRIVER_SENSE 0x08
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "user_strings.h"
|
#include "user_strings.h"
|
||||||
|
@ -63,7 +65,7 @@ void SCSIInit(void)
|
||||||
sprintf(prefs_name, "scsi%d", id);
|
sprintf(prefs_name, "scsi%d", id);
|
||||||
const char *str = PrefsFindString(prefs_name);
|
const char *str = PrefsFindString(prefs_name);
|
||||||
if (str) {
|
if (str) {
|
||||||
int fd = fds[id] = open(str, O_RDWR);
|
int fd = fds[id] = open(str, O_RDWR | O_EXCL);
|
||||||
if (fd > 0) {
|
if (fd > 0) {
|
||||||
// Is it really a Generic SCSI device?
|
// Is it really a Generic SCSI device?
|
||||||
int timeout = ioctl(fd, SG_GET_TIMEOUT);
|
int timeout = ioctl(fd, SG_GET_TIMEOUT);
|
||||||
|
@ -122,7 +124,7 @@ void SCSIExit(void)
|
||||||
|
|
||||||
static bool try_buffer(uint32 size)
|
static bool try_buffer(uint32 size)
|
||||||
{
|
{
|
||||||
size += sizeof(struct sg_header) + 12;
|
size += sizeof(sg_header) + 12;
|
||||||
if (size <= buffer_size)
|
if (size <= buffer_size)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -166,9 +168,9 @@ bool scsi_set_target(int id, int lun)
|
||||||
if (new_fd < 0)
|
if (new_fd < 0)
|
||||||
return false;
|
return false;
|
||||||
if (new_fd != fd) {
|
if (new_fd != fd) {
|
||||||
// Clear autosense data
|
// New target, clear autosense data
|
||||||
struct sg_header *h = (struct sg_header *)buffer;
|
sg_header *h = (sg_header *)buffer;
|
||||||
h->sense_buffer[2] = 0;
|
h->driver_status &= ~DRIVER_SENSE;
|
||||||
}
|
}
|
||||||
fd = new_fd;
|
fd = new_fd;
|
||||||
return true;
|
return true;
|
||||||
|
@ -195,7 +197,7 @@ bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr
|
||||||
// Process S/G table when writing
|
// Process S/G table when writing
|
||||||
if (!reading) {
|
if (!reading) {
|
||||||
D(bug(" writing to buffer\n"));
|
D(bug(" writing to buffer\n"));
|
||||||
uint8 *buffer_ptr = buffer + sizeof(struct sg_header) + the_cmd_len;
|
uint8 *buffer_ptr = buffer + sizeof(sg_header) + the_cmd_len;
|
||||||
for (int i=0; i<sg_size; i++) {
|
for (int i=0; i<sg_size; i++) {
|
||||||
uint32 len = sg_len[i];
|
uint32 len = sg_len[i];
|
||||||
D(bug(" %d bytes from %08lx\n", len, sg_ptr[i]));
|
D(bug(" %d bytes from %08lx\n", len, sg_ptr[i]));
|
||||||
|
@ -205,51 +207,59 @@ bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request Sense and autosense data valid?
|
// Request Sense and autosense data valid?
|
||||||
struct sg_header *h = (struct sg_header *)buffer;
|
sg_header *h = (sg_header *)buffer;
|
||||||
int res;
|
int res;
|
||||||
if (the_cmd[0] == 0x03 && (h->sense_buffer[2] & 0x0f)) {
|
if (reading && the_cmd[0] == 0x03 && (h->target_status & DRIVER_SENSE)) {
|
||||||
|
|
||||||
// Yes, fake command
|
// Yes, fake command
|
||||||
D(bug(" autosense\n"));
|
D(bug(" autosense\n"));
|
||||||
memcpy(buffer + sizeof(struct sg_header), h->sense_buffer, 16);
|
memcpy(buffer + sizeof(sg_header), h->sense_buffer, 16);
|
||||||
|
h->target_status &= ~DRIVER_SENSE;
|
||||||
res = 0;
|
res = 0;
|
||||||
*stat = 0;
|
*stat = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// No, send regular command
|
// No, send regular command
|
||||||
|
if (timeout) {
|
||||||
int to = timeout * HZ / 60;
|
int to = timeout * HZ / 60;
|
||||||
ioctl(fd, SG_SET_TIMEOUT, &to);
|
ioctl(fd, SG_SET_TIMEOUT, &to);
|
||||||
|
}
|
||||||
|
ioctl(fd, SG_NEXT_CMD_LEN, &the_cmd_len);
|
||||||
|
|
||||||
D(bug(" sending command, length %d\n", data_length));
|
D(bug(" sending command, length %d\n", data_length));
|
||||||
|
|
||||||
int request_size, reply_size;
|
int request_size, reply_size;
|
||||||
if (reading) {
|
if (reading) {
|
||||||
h->pack_len = request_size = sizeof(struct sg_header) + the_cmd_len;
|
h->pack_len = request_size = sizeof(sg_header) + the_cmd_len;
|
||||||
h->reply_len = reply_size = sizeof(struct sg_header) + data_length;
|
h->reply_len = reply_size = sizeof(sg_header) + data_length;
|
||||||
} else {
|
} else {
|
||||||
h->pack_len = request_size = sizeof(struct sg_header) + the_cmd_len + data_length;
|
h->pack_len = request_size = sizeof(sg_header) + the_cmd_len + data_length;
|
||||||
h->reply_len = reply_size = sizeof(struct sg_header);
|
h->reply_len = reply_size = sizeof(sg_header);
|
||||||
}
|
}
|
||||||
h->pack_id = pack_id++;
|
h->pack_id = pack_id++;
|
||||||
h->result = 0;
|
h->result = 0;
|
||||||
h->twelve_byte = (the_cmd_len == 12);
|
h->twelve_byte = (the_cmd_len == 12);
|
||||||
h->sense_buffer[2] = 0;
|
h->target_status = 0;
|
||||||
memcpy(buffer + sizeof(struct sg_header), the_cmd, the_cmd_len);
|
h->host_status = 0;
|
||||||
|
h->driver_status = 0;
|
||||||
|
h->other_flags = 0;
|
||||||
|
memcpy(buffer + sizeof(sg_header), the_cmd, the_cmd_len);
|
||||||
|
|
||||||
res = write(fd, buffer, request_size);
|
res = write(fd, buffer, request_size);
|
||||||
D(bug(" request sent, actual %d, result %d\n", res, h->result));
|
D(bug(" request sent, actual %d, result %d\n", res, h->result));
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
res = read(fd, buffer, reply_size);
|
res = read(fd, buffer, reply_size);
|
||||||
D(bug(" reply read, actual %d, result %d\n", res, h->result));
|
D(bug(" reply read, actual %d, result %d, status %02x\n", res, h->result, h->target_status << 1));
|
||||||
}
|
}
|
||||||
if (h->sense_buffer[2] & 0x0f)
|
|
||||||
*stat = 2; // Check condition
|
*stat = h->target_status << 1;
|
||||||
else
|
|
||||||
*stat = 0; // No error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process S/G table when reading
|
// Process S/G table when reading
|
||||||
if (reading && h->result == 0) {
|
if (reading && h->result == 0) {
|
||||||
D(bug(" reading from buffer\n"));
|
D(bug(" reading from buffer\n"));
|
||||||
uint8 *buffer_ptr = buffer + sizeof(struct sg_header);
|
uint8 *buffer_ptr = buffer + sizeof(sg_header);
|
||||||
for (int i=0; i<sg_size; i++) {
|
for (int i=0; i<sg_size; i++) {
|
||||||
uint32 len = sg_len[i];
|
uint32 len = sg_len[i];
|
||||||
D(bug(" %d bytes to %08lx\n", len, sg_ptr[i]));
|
D(bug(" %d bytes to %08lx\n", len, sg_ptr[i]));
|
||||||
|
|
|
@ -96,7 +96,21 @@ static int16 exec_tib(uint32 tib)
|
||||||
uint32 ptr = ReadMacInt32(tib); tib += 4;
|
uint32 ptr = ReadMacInt32(tib); tib += 4;
|
||||||
uint32 len = ReadMacInt32(tib); tib += 4;
|
uint32 len = ReadMacInt32(tib); tib += 4;
|
||||||
|
|
||||||
D(bug(" %d %08x %d\n", cmd, ptr, len));
|
#if DEBUG
|
||||||
|
const char *cmd_str;
|
||||||
|
switch (cmd) {
|
||||||
|
case scInc: cmd_str = "INC "; break;
|
||||||
|
case scNoInc: cmd_str = "NOINC"; break;
|
||||||
|
case scAdd: cmd_str = "ADD "; break;
|
||||||
|
case scMove: cmd_str = "MOVE "; break;
|
||||||
|
case scLoop: cmd_str = "LOOP "; break;
|
||||||
|
case scNop: cmd_str = "NOP "; break;
|
||||||
|
case scStop: cmd_str = "STOP "; break;
|
||||||
|
case scComp: cmd_str = "COMP "; break;
|
||||||
|
default: cmd_str = "??? "; break;
|
||||||
|
}
|
||||||
|
D(bug(" %s(%d) %08x %d\n", cmd_str, cmd, ptr, len));
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case scInc:
|
case scInc:
|
||||||
|
@ -218,7 +232,23 @@ int16 SCSISelect(int id)
|
||||||
|
|
||||||
int16 SCSICmd(int cmd_length, uint8 *cmd)
|
int16 SCSICmd(int cmd_length, uint8 *cmd)
|
||||||
{
|
{
|
||||||
D(bug("SCSICmd len %d, cmd %08x%08x%08x\n", cmd_length, ntohl(0[(uint32 *)cmd]), ntohl(1[(uint32 *)cmd]), ntohl(2[(uint32 *)cmd])));
|
#if DEBUG
|
||||||
|
switch (cmd_length) {
|
||||||
|
case 6:
|
||||||
|
D(bug("SCSICmd len 6, cmd %02x %02x %02x %02x %02x %02x\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]));
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
D(bug("SCSICmd len 10, cmd %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]));
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
D(bug("SCSICmd len 12, cmd %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9], cmd[10], cmd[11]));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
D(bug("SCSICmd bogus length %d\n", cmd_length));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (phase != PH_SELECTED)
|
if (phase != PH_SELECTED)
|
||||||
return scPhaseErr;
|
return scPhaseErr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user