The BusLogic SCSI controller emulation is now fully converted to the SCSI device abstraction layer;
The SCSI device abstraction layer is now in scsi_device.c/h.
This commit is contained in:
@@ -213,7 +213,7 @@ NETOBJ = network.o \
|
|||||||
ip_input.o queue.o tcp_input.o debug.o ip_output.o \
|
ip_input.o queue.o tcp_input.o debug.o ip_output.o \
|
||||||
sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \
|
sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \
|
||||||
net_ne2000.o
|
net_ne2000.o
|
||||||
SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o
|
SCSIOBJ = scsi.o scsi_device.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o
|
||||||
SNDOBJ = sound.o \
|
SNDOBJ = sound.o \
|
||||||
openal.o \
|
openal.o \
|
||||||
dbopl.o nukedopl.o \
|
dbopl.o nukedopl.o \
|
||||||
@@ -552,11 +552,14 @@ scat.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
|
|||||||
scsi.o: 86box.h ibm.h timer.h device.h cdrom.h scsi.h \
|
scsi.o: 86box.h ibm.h timer.h device.h cdrom.h scsi.h \
|
||||||
scsi_aha154x.h scsi_buslogic.h
|
scsi_aha154x.h scsi_buslogic.h
|
||||||
|
|
||||||
|
scsi_device.o: ibm.h scsi.h scsi_disk.h cdrom.h
|
||||||
|
|
||||||
scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \
|
scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \
|
||||||
device.h cdrom.h scsi.h scsi_disk.h scsi_aha154x.h \
|
device.h cdrom.h scsi.h scsi_disk.h scsi_aha154x.h \
|
||||||
|
|
||||||
scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \
|
scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \
|
||||||
device.h scsi.h scsi_disk.h cdrom.h scsi_buslogic.h
|
device.h scsi.h scsi_device.h scsi_disk.h cdrom.h \
|
||||||
|
scsi_buslogic.h
|
||||||
|
|
||||||
scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \
|
scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \
|
||||||
scsi_disk.h timer.h win/plat_iodev.h
|
scsi_disk.h timer.h win/plat_iodev.h
|
||||||
|
|||||||
130
src/scsi.c
130
src/scsi.c
@@ -26,7 +26,6 @@
|
|||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include "scsi_aha154x.h"
|
#include "scsi_aha154x.h"
|
||||||
#include "scsi_buslogic.h"
|
#include "scsi_buslogic.h"
|
||||||
#include "scsi_disk.h"
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE;
|
uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE;
|
||||||
@@ -161,132 +160,3 @@ void SCSIReset(uint8_t id, uint8_t lun)
|
|||||||
SCSIDevices[id][lun].CmdBuffer = NULL;
|
SCSIDevices[id][lun].CmdBuffer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void scsi_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
|
||||||
{
|
|
||||||
if (lun_type == SCSI_DISK)
|
|
||||||
{
|
|
||||||
SCSIPhase = SCSI_PHASE_COMMAND;
|
|
||||||
scsi_hd_command(id, cdb);
|
|
||||||
SCSIStatus = scsi_hd_err_stat_to_scsi(id);
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
SCSIPhase = SCSI_PHASE_COMMAND;
|
|
||||||
cdrom_command(id, cdb);
|
|
||||||
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int scsi_target_phase_to_scsi(int lun_type, uint8_t id)
|
|
||||||
{
|
|
||||||
if (lun_type == SCSI_DISK)
|
|
||||||
{
|
|
||||||
return scsi_hd_phase_to_scsi(id);
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
return cdrom_atapi_phase_to_scsi(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void scsi_target_phase_callback(int lun_type, uint8_t id)
|
|
||||||
{
|
|
||||||
if (lun_type == SCSI_DISK)
|
|
||||||
{
|
|
||||||
scsi_hd_callback(id);
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
cdrom_phase_callback(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int scsi_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
|
||||||
{
|
|
||||||
if (lun_type == SCSI_DISK)
|
|
||||||
{
|
|
||||||
return scsi_hd_err_stat_to_scsi(id);
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
return cdrom_CDROM_PHASE_to_scsi(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SCSI_STATUS_CHECK_CONDITION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void scsi_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte)
|
|
||||||
{
|
|
||||||
if (lun_type == SCSI_DISK)
|
|
||||||
{
|
|
||||||
shdc[id].request_length = cdb_byte;
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
cdrom[id].request_length = cdb_byte;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void scsi_command(int cdb_len, int lun_type, uint8_t id, uint8_t *cdb)
|
|
||||||
{
|
|
||||||
uint8_t phase = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since that field in the target struct is never used when
|
|
||||||
* the bus type is SCSI, let's use it for this scope.
|
|
||||||
*/
|
|
||||||
scsi_target_save_cdb_byte(lun_type, id, cdb[1]);
|
|
||||||
|
|
||||||
if (cdb_len != 12) {
|
|
||||||
/*
|
|
||||||
* Make sure the LUN field of the temporary CDB is always 0,
|
|
||||||
* otherwise Daemon Tools drives will misbehave when a command
|
|
||||||
* is passed through to them.
|
|
||||||
*/
|
|
||||||
cdb[1] &= 0x1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
|
||||||
scsi_target_command(lun_type, id, cdb);
|
|
||||||
if (SCSIStatus == SCSI_STATUS_OK) {
|
|
||||||
phase = scsi_target_phase_to_scsi(lun_type, id);
|
|
||||||
if (phase == 2) {
|
|
||||||
/* Command completed - call the phase callback to complete the command. */
|
|
||||||
scsi_target_phase_callback(lun_type, id);
|
|
||||||
} else {
|
|
||||||
/* Command first phase complete - call the callback to execute the second phase. */
|
|
||||||
scsi_target_phase_callback(lun_type, id);
|
|
||||||
SCSIStatus = scsi_target_err_stat_to_scsi(lun_type, id);
|
|
||||||
/* Command second phase complete - call the callback to complete the command. */
|
|
||||||
scsi_target_phase_callback(lun_type, id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Error (Check Condition) - call the phase callback to complete the command. */
|
|
||||||
scsi_target_phase_callback(lun_type, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -266,8 +266,6 @@ int scsi_card_get_from_internal_name(char *s);
|
|||||||
void scsi_card_init();
|
void scsi_card_init();
|
||||||
void scsi_card_reset(void);
|
void scsi_card_reset(void);
|
||||||
|
|
||||||
void scsi_command(int cdb_len, int lun_type, uint8_t id, uint8_t *cdb);
|
|
||||||
|
|
||||||
extern uint8_t scsi_hard_disks[16][8];
|
extern uint8_t scsi_hard_disks[16][8];
|
||||||
|
|
||||||
int scsi_hd_err_stat_to_scsi(uint8_t id);
|
int scsi_hd_err_stat_to_scsi(uint8_t id);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
|
#include "scsi_device.h"
|
||||||
#include "scsi_disk.h"
|
#include "scsi_disk.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
#include "scsi_buslogic.h"
|
#include "scsi_buslogic.h"
|
||||||
@@ -1107,10 +1108,8 @@ static void
|
|||||||
BuslogicSCSIBIOSRequestSetup(Buslogic_t *bl, uint8_t *CmdBuf, uint8_t *DataInBuf, uint8_t DataReply)
|
BuslogicSCSIBIOSRequestSetup(Buslogic_t *bl, uint8_t *CmdBuf, uint8_t *DataInBuf, uint8_t DataReply)
|
||||||
{
|
{
|
||||||
ESCMD *ESCSICmd = (ESCMD *)CmdBuf;
|
ESCMD *ESCSICmd = (ESCMD *)CmdBuf;
|
||||||
uint8_t hdc_id, cdrom_id;
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t temp_cdb[12];
|
uint8_t temp_cdb[12];
|
||||||
int lun_type = 0;
|
|
||||||
int target_cdb_len = 12;
|
int target_cdb_len = 12;
|
||||||
uint8_t target_id = 0;
|
uint8_t target_id = 0;
|
||||||
|
|
||||||
@@ -1146,24 +1145,9 @@ BuslogicSCSIBIOSRequestSetup(Buslogic_t *bl, uint8_t *CmdBuf, uint8_t *DataInBuf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lun_type = SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].LunType;
|
target_cdb_len = scsi_device_cdb_length(ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||||
|
|
||||||
hdc_id = scsi_hard_disks[ESCSICmd->TargetId][ESCSICmd->LogicalUnit];
|
if (!scsi_device_valid(ESCSICmd->TargetId, ESCSICmd->LogicalUnit)) fatal("SCSI target on %02i:%02i has disappeared\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||||
|
|
||||||
cdrom_id = scsi_cdrom_drives[ESCSICmd->TargetId][ESCSICmd->LogicalUnit];
|
|
||||||
|
|
||||||
if (lun_type == SCSI_DISK)
|
|
||||||
{
|
|
||||||
target_id = hdc_id;
|
|
||||||
target_cdb_len = 12;
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
target_id = cdrom_id;
|
|
||||||
target_cdb_len = cdrom[cdrom_id].cdb_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_id == 0xff) fatal("SCSI target on %02i:%02i has disappeared\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
|
||||||
|
|
||||||
SpecificLog("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id);
|
SpecificLog("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id);
|
||||||
|
|
||||||
@@ -1179,7 +1163,7 @@ BuslogicSCSIBIOSRequestSetup(Buslogic_t *bl, uint8_t *CmdBuf, uint8_t *DataInBuf
|
|||||||
memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len);
|
memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_command(ESCSICmd->CDBLength, lun_type, target_id, temp_cdb);
|
scsi_device_command(ESCSICmd->CDBLength, ESCSICmd->TargetId, ESCSICmd->LogicalUnit, temp_cdb);
|
||||||
|
|
||||||
BuslogicSCSIBIOSDataBufferFree(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
BuslogicSCSIBIOSDataBufferFree(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||||
/* BuslogicSCSIBIOSSenseBufferFree(ESCSICmd, Id, Lun, (SCSIStatus != SCSI_STATUS_OK), 1); */
|
/* BuslogicSCSIBIOSSenseBufferFree(ESCSICmd, Id, Lun, (SCSIStatus != SCSI_STATUS_OK), 1); */
|
||||||
@@ -1235,7 +1219,7 @@ static uint8_t BuslogicCompletionCode(uint8_t *sense)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BuslogicBIOSCommand08(uint8_t id, uint8_t *buffer, int lun_type)
|
uint8_t BuslogicBIOSCommand08(uint8_t id, uint8_t lun, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
@@ -1244,16 +1228,8 @@ uint8_t BuslogicBIOSCommand08(uint8_t id, uint8_t *buffer, int lun_type)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
uint8_t sc = 0;
|
uint8_t sc = 0;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len);
|
||||||
{
|
sc = BuslogicCompletionCode(scsi_device_sense(id, lun));
|
||||||
ret = cdrom_read_capacity(id, cdb, rcbuf, &len);
|
|
||||||
sc = BuslogicCompletionCode(cdrom[id].sense);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = scsi_hd_read_capacity(id, cdb, rcbuf, &len);
|
|
||||||
sc = BuslogicCompletionCode(shdc[id].sense);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
@@ -1277,7 +1253,7 @@ uint8_t BuslogicBIOSCommand08(uint8_t id, uint8_t *buffer, int lun_type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BuslogicBIOSCommand15(uint8_t id, uint8_t *buffer, int lun_type)
|
int BuslogicBIOSCommand15(uint8_t id, uint8_t lun, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
@@ -1286,16 +1262,8 @@ int BuslogicBIOSCommand15(uint8_t id, uint8_t *buffer, int lun_type)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
uint8_t sc = 0;
|
uint8_t sc = 0;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len);
|
||||||
{
|
sc = BuslogicCompletionCode(scsi_device_sense(id, lun));
|
||||||
ret = cdrom_read_capacity(id, cdb, rcbuf, &len);
|
|
||||||
sc = BuslogicCompletionCode(cdrom[id].sense);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = scsi_hd_read_capacity(id, cdb, rcbuf, &len);
|
|
||||||
sc = BuslogicCompletionCode(shdc[id].sense);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer, 0, 6);
|
memset(buffer, 0, 6);
|
||||||
|
|
||||||
@@ -1304,94 +1272,18 @@ int BuslogicBIOSCommand15(uint8_t id, uint8_t *buffer, int lun_type)
|
|||||||
buffer[i] = (ret == 0) ? 0 : rcbuf[i];
|
buffer[i] = (ret == 0) ? 0 : rcbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[4] = (lun_type == SCSI_CDROM) ? 5 : 0;
|
scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5]));
|
||||||
if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
buffer[5] = 0x80;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buffer[5] = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpecificLog("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
|
SpecificLog("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
|
||||||
|
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BuslogicSCSICDROMPhaseHandler(uint8_t id)
|
static void BuslogicIDCheck(uint8_t id, uint8_t lun)
|
||||||
{
|
{
|
||||||
int phase = 0;
|
if (!scsi_device_valid(id, lun))
|
||||||
|
|
||||||
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(id);
|
|
||||||
if (SCSIStatus == SCSI_STATUS_OK)
|
|
||||||
{
|
{
|
||||||
phase = cdrom_atapi_phase_to_scsi(id);
|
fatal("BIOS INT13 CD-ROM on %02i:%02i has disappeared\n", id, lun);
|
||||||
if (phase == 2)
|
|
||||||
{
|
|
||||||
/* Command completed - call the phase callback to complete the command. */
|
|
||||||
cdrom_phase_callback(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Command first phase complete - call the callback to execute the second phase. */
|
|
||||||
cdrom_phase_callback(id);
|
|
||||||
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(id);
|
|
||||||
/* Command second phase complete - call the callback to complete the command. */
|
|
||||||
cdrom_phase_callback(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Error (Check Condition) - call the phase callback to complete the command. */
|
|
||||||
cdrom_phase_callback(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BuslogicSCSIDiskPhaseHandler(uint8_t hdc_id)
|
|
||||||
{
|
|
||||||
int phase = 0;
|
|
||||||
|
|
||||||
SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id);
|
|
||||||
if (SCSIStatus == SCSI_STATUS_OK)
|
|
||||||
{
|
|
||||||
phase = scsi_hd_phase_to_scsi(hdc_id);
|
|
||||||
if (phase == 2)
|
|
||||||
{
|
|
||||||
/* Command completed - call the phase callback to complete the command. */
|
|
||||||
scsi_hd_callback(hdc_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Command first phase complete - call the callback to execute the second phase. */
|
|
||||||
scsi_hd_callback(hdc_id);
|
|
||||||
SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id);
|
|
||||||
/* Command second phase complete - call the callback to complete the command. */
|
|
||||||
scsi_hd_callback(hdc_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Error (Check Condition) - call the phase callback to complete the command. */
|
|
||||||
scsi_hd_callback(hdc_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BuslogicIDCheck(int lun_type, uint8_t cdrom_id, uint8_t hdc_id, BIOSCMD *BiosCmd)
|
|
||||||
{
|
|
||||||
if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
if (cdrom_id == 0xff)
|
|
||||||
{
|
|
||||||
fatal("BIOS INT13 CD-ROM on %02i:%02i has disappeared\n", BiosCmd->id, BiosCmd->lun);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hdc_id == 0xff)
|
|
||||||
{
|
|
||||||
fatal("BIOS INT13 hard disk on %02i:%02i has disappeared\n", BiosCmd->id, BiosCmd->lun);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1399,11 +1291,9 @@ static void BuslogicIDCheck(int lun_type, uint8_t cdrom_id, uint8_t hdc_id, BIOS
|
|||||||
uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
||||||
{
|
{
|
||||||
uint32_t dma_address;
|
uint32_t dma_address;
|
||||||
uint8_t cdrom_id, hdc_id;
|
|
||||||
int lba = (BiosCmd->cylinder << 9) + (BiosCmd->head << 5) + BiosCmd->sector;
|
int lba = (BiosCmd->cylinder << 9) + (BiosCmd->head << 5) + BiosCmd->sector;
|
||||||
int sector_len = BiosCmd->secount;
|
int sector_len = BiosCmd->secount;
|
||||||
int block_shift = 9;
|
int block_shift = 9;
|
||||||
int lun_type = SCSI_NONE;
|
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
@@ -1413,14 +1303,9 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
return 0x80;
|
return 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
lun_type = SCSIDevices[BiosCmd->id][BiosCmd->lun].LunType;
|
|
||||||
|
|
||||||
cdrom_id = scsi_cdrom_drives[BiosCmd->id][BiosCmd->lun];
|
|
||||||
hdc_id = scsi_hard_disks[BiosCmd->id][BiosCmd->lun];
|
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 0;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 0;
|
||||||
|
|
||||||
if (lun_type == SCSI_NONE)
|
if (!scsi_device_present(BiosCmd->id, BiosCmd->lun))
|
||||||
{
|
{
|
||||||
SpecificLog("BIOS Target ID %i and LUN %i have no device attached\n",BiosCmd->id,BiosCmd->lun);
|
SpecificLog("BIOS Target ID %i and LUN %i have no device attached\n",BiosCmd->id,BiosCmd->lun);
|
||||||
return 0x80;
|
return 0x80;
|
||||||
@@ -1436,6 +1321,8 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block_shift = scsi_device_block_shift(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
switch(BiosCmd->command)
|
switch(BiosCmd->command)
|
||||||
{
|
{
|
||||||
case 0x00: /* Reset Disk System, in practice it's a nop */
|
case 0x00: /* Reset Disk System, in practice it's a nop */
|
||||||
@@ -1444,7 +1331,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: /* Read Status of Last Operation */
|
case 0x01: /* Read Status of Last Operation */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
/* Assuming 14 bytes because that's the default length for SCSI sense, and no command-specific
|
/* Assuming 14 bytes because that's the default length for SCSI sense, and no command-specific
|
||||||
indication is given. */
|
indication is given. */
|
||||||
@@ -1453,19 +1340,12 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(14);
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(14);
|
||||||
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 14);
|
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 14);
|
||||||
|
|
||||||
SCSIStatus = BuslogicBIOSCommand08((lun_type == SCSI_CDROM) ? cdrom_id : hdc_id, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, lun_type) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION;
|
/* SCSIStatus = BuslogicBIOSCommand08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION; */
|
||||||
|
|
||||||
if (sector_len > 0)
|
if (sector_len > 0)
|
||||||
{
|
{
|
||||||
SpecificLog("BusLogic BIOS DMA: Reading 14 bytes at %08X\n", dma_address);
|
SpecificLog("BusLogic BIOS DMA: Reading 14 bytes at %08X\n", dma_address);
|
||||||
if (lun_type == SCSI_CDROM)
|
DMAPageWrite(dma_address, (char *)scsi_device_sense(BiosCmd->id, BiosCmd->lun), 14);
|
||||||
{
|
|
||||||
DMAPageWrite(dma_address, (char *)cdrom[cdrom_id].sense, 14);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DMAPageWrite(dma_address, (char *)shdc[hdc_id].sense, 14);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
|
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
|
||||||
@@ -1474,17 +1354,12 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02: /* Read Desired Sectors to Memory */
|
case 0x02: /* Read Desired Sectors to Memory */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
block_shift = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift;
|
||||||
|
|
||||||
@@ -1492,6 +1367,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, sector_len << block_shift);
|
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, sector_len << block_shift);
|
||||||
|
|
||||||
cdb[0] = GPCMD_READ_10;
|
cdb[0] = GPCMD_READ_10;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
cdb[2] = (lba >> 24) & 0xff;
|
cdb[2] = (lba >> 24) & 0xff;
|
||||||
cdb[3] = (lba >> 16) & 0xff;
|
cdb[3] = (lba >> 16) & 0xff;
|
||||||
cdb[4] = (lba >> 8) & 0xff;
|
cdb[4] = (lba >> 8) & 0xff;
|
||||||
@@ -1499,18 +1375,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[7] = (sector_len >> 8) & 0xff;
|
cdb[7] = (sector_len >> 8) & 0xff;
|
||||||
cdb[8] = sector_len & 0xff;
|
cdb[8] = sector_len & 0xff;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sector_len > 0)
|
if (sector_len > 0)
|
||||||
{
|
{
|
||||||
@@ -1524,17 +1389,12 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03: /* Write Desired Sectors from Memory */
|
case 0x03: /* Write Desired Sectors from Memory */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
block_shift = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift;
|
||||||
|
|
||||||
@@ -1548,6 +1408,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cdb[0] = GPCMD_WRITE_10;
|
cdb[0] = GPCMD_WRITE_10;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
cdb[2] = (lba >> 24) & 0xff;
|
cdb[2] = (lba >> 24) & 0xff;
|
||||||
cdb[3] = (lba >> 16) & 0xff;
|
cdb[3] = (lba >> 16) & 0xff;
|
||||||
cdb[4] = (lba >> 8) & 0xff;
|
cdb[4] = (lba >> 8) & 0xff;
|
||||||
@@ -1555,18 +1416,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[7] = (sector_len >> 8) & 0xff;
|
cdb[7] = (sector_len >> 8) & 0xff;
|
||||||
cdb[8] = sector_len & 0xff;
|
cdb[8] = sector_len & 0xff;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
|
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
|
||||||
{
|
{
|
||||||
@@ -1574,19 +1424,15 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: /* Verify Desired Sectors */
|
case 0x04: /* Verify Desired Sectors */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
block_shift = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
cdb[0] = GPCMD_VERIFY_10;
|
cdb[0] = GPCMD_VERIFY_10;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
cdb[2] = (lba >> 24) & 0xff;
|
cdb[2] = (lba >> 24) & 0xff;
|
||||||
cdb[3] = (lba >> 16) & 0xff;
|
cdb[3] = (lba >> 16) & 0xff;
|
||||||
cdb[4] = (lba >> 8) & 0xff;
|
cdb[4] = (lba >> 8) & 0xff;
|
||||||
@@ -1594,20 +1440,9 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[7] = (sector_len >> 8) & 0xff;
|
cdb[7] = (sector_len >> 8) & 0xff;
|
||||||
cdb[8] = sector_len & 0xff;
|
cdb[8] = sector_len & 0xff;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1622,36 +1457,26 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07: /* Format Unit */
|
case 0x07: /* Format Unit */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
cdb[0] = GPCMD_FORMAT_UNIT;
|
cdb[0] = GPCMD_FORMAT_UNIT;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: /* Read Drive Parameters */
|
case 0x08: /* Read Drive Parameters */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6;
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6);
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6);
|
||||||
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6);
|
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6);
|
||||||
|
|
||||||
ret = BuslogicBIOSCommand08((lun_type == SCSI_CDROM) ? cdrom_id : hdc_id, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, lun_type);
|
ret = BuslogicBIOSCommand08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer);
|
||||||
|
|
||||||
SpecificLog("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
SpecificLog("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||||
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6);
|
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6);
|
||||||
@@ -1672,28 +1497,18 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0C: /* Seek */
|
case 0x0C: /* Seek */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift;
|
||||||
|
|
||||||
cdb[0] = GPCMD_SEEK_10;
|
cdb[0] = GPCMD_SEEK_10;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
cdb[2] = (lba >> 24) & 0xff;
|
cdb[2] = (lba >> 24) & 0xff;
|
||||||
cdb[3] = (lba >> 16) & 0xff;
|
cdb[3] = (lba >> 16) & 0xff;
|
||||||
cdb[4] = (lba >> 8) & 0xff;
|
cdb[4] = (lba >> 8) & 0xff;
|
||||||
cdb[5] = lba & 0xff;
|
cdb[5] = lba & 0xff;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (SCSIStatus == SCSI_STATUS_OK) ? 1 : 0;
|
return (SCSIStatus == SCSI_STATUS_OK) ? 1 : 0;
|
||||||
|
|
||||||
@@ -1705,46 +1520,26 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10: /* Test Drive Ready */
|
case 0x10: /* Test Drive Ready */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
cdb[0] = GPCMD_TEST_UNIT_READY;
|
cdb[0] = GPCMD_TEST_UNIT_READY;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x11: /* Recalibrate */
|
case 0x11: /* Recalibrate */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
cdb[0] = GPCMD_REZERO_UNIT;
|
cdb[0] = GPCMD_REZERO_UNIT;
|
||||||
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
|
|
||||||
if (lun_type == SCSI_CDROM)
|
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
||||||
{
|
|
||||||
cdrom[cdrom_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
cdrom_command(cdrom_id, cdb);
|
|
||||||
BuslogicSCSICDROMPhaseHandler(cdrom_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shdc[hdc_id].request_length = (BiosCmd->lun & 7) << 5;
|
|
||||||
scsi_hd_command(hdc_id, cdb);
|
|
||||||
BuslogicSCSIDiskPhaseHandler(hdc_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuslogicCompletionCode((lun_type == SCSI_CDROM) ? cdrom[cdrom_id].sense : shdc[hdc_id].sense);
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1754,14 +1549,14 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x15: /* Read DASD Type */
|
case 0x15: /* Read DASD Type */
|
||||||
BuslogicIDCheck(lun_type, cdrom_id, hdc_id, BiosCmd);
|
BuslogicIDCheck(BiosCmd->id, BiosCmd->lun);
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6;
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6;
|
||||||
|
|
||||||
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6);
|
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6);
|
||||||
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6);
|
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6);
|
||||||
|
|
||||||
ret = BuslogicBIOSCommand15((lun_type == SCSI_CDROM) ? cdrom_id : hdc_id, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, lun_type);
|
ret = BuslogicBIOSCommand15(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer);
|
||||||
|
|
||||||
SpecificLog("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
SpecificLog("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||||
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6);
|
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6);
|
||||||
@@ -2532,33 +2327,18 @@ BuslogicSCSICommand(Buslogic_t *bl)
|
|||||||
{
|
{
|
||||||
Req_t *req = &bl->Req;
|
Req_t *req = &bl->Req;
|
||||||
uint8_t Id, Lun;
|
uint8_t Id, Lun;
|
||||||
uint8_t hdc_id, cdrom_id;
|
|
||||||
uint8_t temp_cdb[12];
|
uint8_t temp_cdb[12];
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int lun_type = SCSI_NONE;
|
|
||||||
uint8_t target_id = 0;
|
|
||||||
int target_cdb_len = 12;
|
int target_cdb_len = 12;
|
||||||
|
|
||||||
Id = req->TargetID;
|
Id = req->TargetID;
|
||||||
Lun = req->LUN;
|
Lun = req->LUN;
|
||||||
lun_type = SCSIDevices[Id][Lun].LunType;
|
|
||||||
hdc_id = scsi_hard_disks[Id][Lun];
|
|
||||||
cdrom_id = scsi_cdrom_drives[Id][Lun];
|
|
||||||
|
|
||||||
if (lun_type == SCSI_DISK)
|
target_cdb_len = scsi_device_cdb_length(Id, Lun);
|
||||||
{
|
|
||||||
target_id = hdc_id;
|
|
||||||
target_cdb_len = 12;
|
|
||||||
}
|
|
||||||
else if (lun_type == SCSI_CDROM)
|
|
||||||
{
|
|
||||||
target_id = cdrom_id;
|
|
||||||
target_cdb_len = cdrom[cdrom_id].cdb_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_id == 0xff) fatal("Target on %02i:%02i has disappeared\n", Id, Lun);
|
if (!scsi_device_valid(Id, Lun)) fatal("Target on %02i:%02i has disappeared\n", Id, Lun);
|
||||||
|
|
||||||
pclog("Target command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id);
|
pclog("Target command being executed on: SCSI ID %i, SCSI LUN %i\n", Id, Lun);
|
||||||
|
|
||||||
pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]);
|
pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]);
|
||||||
for (i = 1; i < req->CmdBlock.common.CdbLength; i++) {
|
for (i = 1; i < req->CmdBlock.common.CdbLength; i++) {
|
||||||
@@ -2573,7 +2353,7 @@ BuslogicSCSICommand(Buslogic_t *bl)
|
|||||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len);
|
memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_command(req->CmdBlock.common.CdbLength, SCSIDevices[Id][Lun].LunType, target_id, temp_cdb);
|
scsi_device_command(req->CmdBlock.common.CdbLength, Id, Lun, temp_cdb);
|
||||||
|
|
||||||
BuslogicDataBufferFree(req);
|
BuslogicDataBufferFree(req);
|
||||||
|
|
||||||
@@ -2620,7 +2400,7 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb
|
|||||||
|
|
||||||
BuslogicDataBufferAllocate(req, req->Is24bit);
|
BuslogicDataBufferAllocate(req, req->Is24bit);
|
||||||
|
|
||||||
if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) {
|
if (!scsi_device_present(Id, Lun)) {
|
||||||
pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun);
|
pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun);
|
||||||
BuslogicDataBufferFree(req);
|
BuslogicDataBufferFree(req);
|
||||||
BuslogicSenseBufferFree(req, 0, 0);
|
BuslogicSenseBufferFree(req, 0, 0);
|
||||||
|
|||||||
285
src/scsi_device.c
Normal file
285
src/scsi_device.c
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
#include "ibm.h"
|
||||||
|
#include "scsi.h"
|
||||||
|
#include "scsi_disk.h"
|
||||||
|
#include "cdrom.h"
|
||||||
|
|
||||||
|
static uint8_t scsi_null_device_sense[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static void scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
||||||
|
{
|
||||||
|
if (lun_type == SCSI_DISK)
|
||||||
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_COMMAND;
|
||||||
|
scsi_hd_command(id, cdb);
|
||||||
|
SCSIStatus = scsi_hd_err_stat_to_scsi(id);
|
||||||
|
}
|
||||||
|
else if (lun_type == SCSI_CDROM)
|
||||||
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_COMMAND;
|
||||||
|
cdrom_command(id, cdb);
|
||||||
|
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int scsi_device_target_phase_to_scsi(int lun_type, uint8_t id)
|
||||||
|
{
|
||||||
|
if (lun_type == SCSI_DISK)
|
||||||
|
{
|
||||||
|
return scsi_hd_phase_to_scsi(id);
|
||||||
|
}
|
||||||
|
else if (lun_type == SCSI_CDROM)
|
||||||
|
{
|
||||||
|
return cdrom_atapi_phase_to_scsi(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||||
|
{
|
||||||
|
if (lun_type == SCSI_DISK)
|
||||||
|
{
|
||||||
|
scsi_hd_callback(id);
|
||||||
|
}
|
||||||
|
else if (lun_type == SCSI_CDROM)
|
||||||
|
{
|
||||||
|
cdrom_phase_callback(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||||
|
{
|
||||||
|
if (lun_type == SCSI_DISK)
|
||||||
|
{
|
||||||
|
return scsi_hd_err_stat_to_scsi(id);
|
||||||
|
}
|
||||||
|
else if (lun_type == SCSI_CDROM)
|
||||||
|
{
|
||||||
|
return cdrom_CDROM_PHASE_to_scsi(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SCSI_STATUS_CHECK_CONDITION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte)
|
||||||
|
{
|
||||||
|
if (lun_type == SCSI_DISK)
|
||||||
|
{
|
||||||
|
shdc[id].request_length = cdb_byte;
|
||||||
|
}
|
||||||
|
else if (lun_type == SCSI_CDROM)
|
||||||
|
{
|
||||||
|
cdrom[id].request_length = cdb_byte;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_DISK:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
return shdc[id].sense;
|
||||||
|
break;
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||||
|
return cdrom[id].sense;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return scsi_null_device_sense;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_DISK:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
*type = 0x00;
|
||||||
|
*rmb = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00;
|
||||||
|
break;
|
||||||
|
case SCSI_CDROM:
|
||||||
|
*type = 0x05;
|
||||||
|
*rmb = 0x80;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*type = *rmb = 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_DISK:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
return scsi_hd_read_capacity(id, cdb, buffer, len);
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
return cdrom_read_capacity(id, cdb, buffer, len);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_NONE:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_DISK:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
break;
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
id = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (id == 0xFF) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||||
|
return cdrom[id].cdb_len;
|
||||||
|
default:
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int scsi_device_block_shift(uint8_t scsi_id, uint8_t scsi_lun)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_CDROM:
|
||||||
|
return 11; /* 2048 bytes per block */
|
||||||
|
default:
|
||||||
|
return 9; /* 512 bytes per block */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scsi_device_command(int cdb_len, uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb)
|
||||||
|
{
|
||||||
|
uint8_t phase = 0;
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_DISK:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
break;
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
id = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since that field in the target struct is never used when
|
||||||
|
* the bus type is SCSI, let's use it for this scope.
|
||||||
|
*/
|
||||||
|
scsi_device_target_save_cdb_byte(lun_type, id, cdb[1]);
|
||||||
|
|
||||||
|
if (cdb_len != 12) {
|
||||||
|
/*
|
||||||
|
* Make sure the LUN field of the temporary CDB is always 0,
|
||||||
|
* otherwise Daemon Tools drives will misbehave when a command
|
||||||
|
* is passed through to them.
|
||||||
|
*/
|
||||||
|
cdb[1] &= 0x1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
||||||
|
scsi_device_target_command(lun_type, id, cdb);
|
||||||
|
if (SCSIStatus == SCSI_STATUS_OK) {
|
||||||
|
phase = scsi_device_target_phase_to_scsi(lun_type, id);
|
||||||
|
if (phase == 2) {
|
||||||
|
/* Command completed - call the phase callback to complete the command. */
|
||||||
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
|
} else {
|
||||||
|
/* Command first phase complete - call the callback to execute the second phase. */
|
||||||
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
|
SCSIStatus = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||||
|
/* Command second phase complete - call the callback to complete the command. */
|
||||||
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Error (Check Condition) - call the phase callback to complete the command. */
|
||||||
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/scsi_device.h
Normal file
8
src/scsi_device.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun);
|
||||||
|
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb);
|
||||||
|
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||||
|
int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun);
|
||||||
|
int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun);
|
||||||
|
int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun);
|
||||||
|
int scsi_device_block_shift(uint8_t scsi_id, uint8_t scsi_lun);
|
||||||
|
void scsi_device_command(int cdb_len, uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb);
|
||||||
Reference in New Issue
Block a user