SCSI cleanup and finishing of the AHA-1640 driver. Boots fine, fully auto-config through MCA.

This commit is contained in:
waltje
2017-08-27 21:46:51 -04:00
parent d58eb9dac0
commit 90d7b71e5e
5 changed files with 989 additions and 1001 deletions

View File

@@ -8,7 +8,7 @@
# #
# Modified Makefile for Win32 (MinGW32) environment. # Modified Makefile for Win32 (MinGW32) environment.
# #
# Version: @(#)Makefile.mingw 1.0.39 2017/08/26 # Version: @(#)Makefile.mingw 1.0.40 2017/08/27
# #
# Authors: Miran Grca, <mgrca8@gmail.com> # Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com> # Fred N. van Kempen, <decwiz@yahoo.com>
@@ -28,7 +28,9 @@ STUFF =
# -DANSI_CFG forces the config file to ANSI encoding. # -DANSI_CFG forces the config file to ANSI encoding.
# -DENABLE_VRAM_DUMP enables Video Ram dumping. # -DENABLE_VRAM_DUMP enables Video Ram dumping.
# -DENABLE_LOG_BREAKPOINT enables extra logging. # -DENABLE_LOG_BREAKPOINT enables extra logging.
# -DENABLE_BUSLOGIC_LOG enables extra logging. # -DENABLE_SCSI_BIOS_COMMAND_LOG=n enables extra logging.
# -DENABLE_AHA154X_LOG=n enables extra logging.
# -DENABLE_BUSLOGIC_LOG=n enables extra logging.
# -DENABLE_CDROM_LOG enables extra logging. # -DENABLE_CDROM_LOG enables extra logging.
# -DENABLE_D86F_LOG enables extra logging. # -DENABLE_D86F_LOG enables extra logging.
# -DENABLE_FDC_LOG enables extra logging. # -DENABLE_FDC_LOG enables extra logging.

View File

@@ -8,12 +8,11 @@
* *
* Handling of the SCSI controllers. * Handling of the SCSI controllers.
* *
* Version: @(#)scsi.c 1.0.2 2017/08/23 * Version: @(#)scsi.c 1.0.3 2017/08/27
* *
* Authors: TheCollector1995, <mariogplayer@gmail.com> * Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2008-2017 TheCollector1995.
* Copyright 2016,2017 Miran Grca. * Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen. * Copyright 2017 Fred N. van Kempen.
*/ */
@@ -29,6 +28,7 @@
#include "scsi_buslogic.h" #include "scsi_buslogic.h"
scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE;
uint8_t SCSIStatus = SCSI_STATUS_OK; uint8_t SCSIStatus = SCSI_STATUS_OK;
uint8_t scsi_cdrom_id = 3; /*common setting*/ uint8_t scsi_cdrom_id = 3; /*common setting*/
@@ -116,18 +116,13 @@ void scsi_card_init(void)
pclog("Building SCSI CD-ROM map...\n"); pclog("Building SCSI CD-ROM map...\n");
build_scsi_cdrom_map(); build_scsi_cdrom_map();
for (i=0; i<16; i++) for (i=0; i<SCSI_ID_MAX; i++) {
{ for (j=0; j<SCSI_LUN_MAX; j++) {
for (j=0; j<8; j++)
{
if (scsi_hard_disks[i][j] != 0xff) { if (scsi_hard_disks[i][j] != 0xff) {
SCSIDevices[i][j].LunType = SCSI_DISK; SCSIDevices[i][j].LunType = SCSI_DISK;
} } else if (scsi_cdrom_drives[i][j] != 0xff) {
else if (scsi_cdrom_drives[i][j] != 0xff) {
SCSIDevices[i][j].LunType = SCSI_CDROM; SCSIDevices[i][j].LunType = SCSI_CDROM;
} } else {
else
{
SCSIDevices[i][j].LunType = SCSI_NONE; SCSIDevices[i][j].LunType = SCSI_NONE;
} }
} }
@@ -144,13 +139,10 @@ void scsi_card_reset(void)
{ {
void *p = NULL; void *p = NULL;
if (scsi_cards[scsi_card_current].device) if (scsi_cards[scsi_card_current].device) {
{
p = device_get_priv(scsi_cards[scsi_card_current].device); p = device_get_priv(scsi_cards[scsi_card_current].device);
if (p) if (p) {
{ if (scsi_cards[scsi_card_current].reset) {
if (scsi_cards[scsi_card_current].reset)
{
scsi_cards[scsi_card_current].reset(p); scsi_cards[scsi_card_current].reset(p);
} }
} }
@@ -168,19 +160,15 @@ void SCSIReset(uint8_t id, uint8_t lun)
scsi_hd_reset(cdrom_id); scsi_hd_reset(cdrom_id);
SCSIDevices[id][lun].LunType = SCSI_DISK; SCSIDevices[id][lun].LunType = SCSI_DISK;
} else { } else {
if (cdrom_id != 0xff) if (cdrom_id != 0xff) {
{
cdrom_reset(cdrom_id); cdrom_reset(cdrom_id);
SCSIDevices[id][lun].LunType = SCSI_CDROM; SCSIDevices[id][lun].LunType = SCSI_CDROM;
} } else {
else
{
SCSIDevices[id][lun].LunType = SCSI_NONE; SCSIDevices[id][lun].LunType = SCSI_NONE;
} }
} }
if(SCSIDevices[id][lun].CmdBuffer != NULL) if (SCSIDevices[id][lun].CmdBuffer != NULL) {
{
free(SCSIDevices[id][lun].CmdBuffer); free(SCSIDevices[id][lun].CmdBuffer);
SCSIDevices[id][lun].CmdBuffer = NULL; SCSIDevices[id][lun].CmdBuffer = NULL;
} }

View File

@@ -8,7 +8,7 @@
* *
* SCSI controller handler header. * SCSI controller handler header.
* *
* Version: @(#)scsi_h 1.0.4 2017/08/26 * Version: @(#)scsi_h 1.0.5 2017/08/27
* *
* Authors: TheCollector1995, <mariogplayer@gmail.com> * Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -28,6 +28,11 @@
#endif #endif
/* Configuration. */
#define SCSI_ID_MAX 8 /* 16 on wide buses */
#define SCSI_LUN_MAX 8 /* always 8 */
/* SCSI commands. */ /* SCSI commands. */
#define GPCMD_TEST_UNIT_READY 0x00 #define GPCMD_TEST_UNIT_READY 0x00
#define GPCMD_REZERO_UNIT 0x01 #define GPCMD_REZERO_UNIT 0x01
@@ -193,20 +198,19 @@
#define CHECK_READY 2 #define CHECK_READY 2
#define ALLOW_UA 1 #define ALLOW_UA 1
extern uint8_t SCSICommandTable[0x100]; extern uint8_t SCSICommandTable[0x100];
extern uint8_t mode_sense_pages[0x40]; extern uint8_t mode_sense_pages[0x40];
extern int readcdmode; extern int readcdmode;
/* Mode sense/select stuff. */ /* Mode sense/select stuff. */
extern uint8_t mode_pages_in[256][256]; extern uint8_t mode_pages_in[256][256];
#define PAGE_CHANGEABLE 1
#define PAGE_CHANGED 2
extern uint8_t page_flags[256]; extern uint8_t page_flags[256];
extern uint8_t prefix_len; extern uint8_t prefix_len;
extern uint8_t page_current; extern uint8_t page_current;
#define PAGE_CHANGEABLE 1
#define PAGE_CHANGED 2
extern uint32_t DataLength; extern uint32_t DataLength;
extern uint32_t DataPointer; extern uint32_t DataPointer;
@@ -220,8 +224,7 @@ extern uint8_t SCSIStatus;
extern uint8_t SCSIPhase; extern uint8_t SCSIPhase;
extern uint8_t scsi_cdrom_id; extern uint8_t scsi_cdrom_id;
struct struct {
{
uint8_t SenseBuffer[18]; uint8_t SenseBuffer[18];
uint8_t SenseLength; uint8_t SenseLength;
uint8_t UnitAttention; uint8_t UnitAttention;
@@ -248,13 +251,16 @@ extern int prev_status;
#define SCSI_PHASE_BUS_FREE ( 8 ) #define SCSI_PHASE_BUS_FREE ( 8 )
#define SCSI_PHASE_SELECT ( 9 ) #define SCSI_PHASE_SELECT ( 9 )
struct
{ typedef struct {
uint8_t *CmdBuffer; uint8_t *CmdBuffer;
uint32_t CmdBufferLength; uint32_t CmdBufferLength;
int LunType; int LunType;
uint32_t InitLength; uint32_t InitLength;
} SCSIDevices[16][8]; } scsi_device_t;
extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
extern void SCSIReset(uint8_t id, uint8_t lun); extern void SCSIReset(uint8_t id, uint8_t lun);

File diff suppressed because it is too large Load Diff

View File

@@ -8,230 +8,256 @@
* *
* The shared AHA and Buslogic SCSI BIOS command handler. * The shared AHA and Buslogic SCSI BIOS command handler.
* *
* Version: @(#)scsi_bios_command.c 1.0.0 2017/08/26 * Version: @(#)scsi_bios_command.c 1.0.1 2017/08/27
* *
* Authors: TheCollector1995, <mariogplayer@gmail.com> * Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2016,2017 Miran Grca. * Copyright 2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen. * Copyright 2017 Fred N. van Kempen.
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include "../ibm.h" #include "../ibm.h"
#include "../dma.h" #include "../dma.h"
#include "scsi.h" #include "scsi.h"
#include "scsi_bios_command.h" #include "scsi_bios_command.h"
#include "scsi_device.h" #include "scsi_device.h"
/* #define ENABLE_SCSI_BIOS_COMMAND_LOG 0 */
int scsi_bios_command_do_log = 0; #if ENABLE_SCSI_BIOS_COMMAND_LOG
int scsi_bios_command_do_log = ENABLE_SCSI_BIOS_COMMAND_LOG;
#endif
static void static void
scsi_bios_command_log(const char *format, ...) cmd_log(const char *fmt, ...)
{ {
#ifdef ENABLE_SCSI_BIOS_COMMAND_LOG #if ENABLE_SCSI_BIOS_COMMAND_LOG
if (scsi_bios_command_do_log)
{
va_list ap; va_list ap;
va_start(ap, format); if (scsi_bios_command_do_log) {
vprintf(format, ap); va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap); va_end(ap);
fflush(stdout); fflush(stdout);
} }
#endif #endif
} }
static uint8_t scsi_bios_completion_code(uint8_t *sense)
static void
target_check(uint8_t id, uint8_t lun)
{ {
switch (sense[12]) if (! scsi_device_valid(id, lun)) {
{ fatal("BIOS INT13 device on %02i:%02i has disappeared\n", id, lun);
}
}
static uint8_t
completion_code(uint8_t *sense)
{
switch (sense[12]) {
case 0x00: case 0x00:
return 0x00; return(0x00);
case 0x20: case 0x20:
return 0x01; return(0x01);
case 0x12: case 0x12:
case 0x21: case 0x21:
return 0x02; return(0x02);
case 0x27: case 0x27:
return 0x03; return(0x03);
case 0x14: case 0x16:
return 0x04; case 0x14:
case 0x10: case 0x11: case 0x16:
return 0x10; return(0x04);
case 0x17: case 0x18:
return 0x11; case 0x10:
case 0x01: case 0x03: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x11:
case 0x1B: case 0x1C: case 0x1D: return(0x10);
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46:
case 0x47: case 0x48: case 0x49: case 0x17:
return 0x20; case 0x18:
return(0x11);
case 0x01:
case 0x03:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
case 0x48:
case 0x49:
return(0x20);
case 0x15: case 0x15:
case 0x02: case 0x02:
return 0x40; return(0x40);
case 0x04: case 0x04:
case 0x28: case 0x29: case 0x2A: case 0x28:
return 0xAA; case 0x29:
case 0x2a:
return(0xaa);
default: default:
return 0xFF; break;
} };
return(0xff);
} }
uint8_t scsi_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer)
uint8_t
scsi_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer)
{ {
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 };
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
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 }; int i, ret, sc;
uint8_t rcbuf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int ret = 0;
int i = 0;
uint8_t sc = 0;
ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len);
sc = scsi_bios_completion_code(scsi_device_sense(id, lun)); sc = completion_code(scsi_device_sense(id, lun));
if (ret == 0) return(sc);
if (ret == 0) memset(buffer, 0x00, 6);
{ for (i=0; i<4; i++)
return sc;
}
memset(buffer, 0, 6);
for (i = 0; i < 4; i++)
{
buffer[i] = rcbuf[i]; buffer[i] = rcbuf[i];
} for (i=4; i<6; i++)
for (i = 4; i < 6; i++)
{
buffer[i] = rcbuf[(i + 2) ^ 1]; buffer[i] = rcbuf[(i + 2) ^ 1];
} cmd_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n",
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
scsi_bios_command_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); return(0);
return 0;
} }
int scsi_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer)
int
scsi_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer)
{ {
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 };
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
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 }; int i, ret, sc;
uint8_t rcbuf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int ret = 0;
int i = 0;
uint8_t sc = 0;
ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len);
sc = scsi_bios_completion_code(scsi_device_sense(id, lun)); sc = completion_code(scsi_device_sense(id, lun));
memset(buffer, 0, 6); memset(buffer, 0x00, 6);
for (i=0; i<4; i++)
for (i = 0; i < 4; i++)
{
buffer[i] = (ret == 0) ? 0 : rcbuf[i]; buffer[i] = (ret == 0) ? 0 : rcbuf[i];
}
scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5])); scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5]));
scsi_bios_command_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); cmd_log("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 scsi_bios_command_id_check(uint8_t id, uint8_t lun)
{
if (!scsi_device_valid(id, lun))
{
fatal("BIOS INT13 CD-ROM on %02i:%02i has disappeared\n", id, lun);
}
} }
/* This returns the completion code. */ /* This returns the completion code. */
uint8_t scsi_bios_command(uint8_t last_id, BIOSCMD *BiosCmd, int8_t islba) uint8_t
scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
{ {
uint8_t cdb[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 };
scsi_device_t *dev;
uint32_t dma_address; uint32_t dma_address;
uint32_t lba; uint32_t lba;
int sector_len = BiosCmd->secount; int sector_len = cmd->secount;
int block_shift = 9; int block_shift;
uint8_t ret = 0; uint8_t ret;
uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
if (islba) if (islba)
lba = lba32_blk(BiosCmd); lba = lba32_blk(cmd);
else else
lba = (BiosCmd->u.chs.cyl << 9) + (BiosCmd->u.chs.head << 5) + BiosCmd->u.chs.sec; lba = (cmd->u.chs.cyl << 9) + (cmd->u.chs.head << 5) + cmd->u.chs.sec;
scsi_bios_command_log("BIOS Command = 0x%02X\n", BiosCmd->command); cmd_log("BIOS Command = 0x%02X\n", cmd->command);
if ((BiosCmd->id > last_id) || (BiosCmd->lun > 7)) { if ((cmd->id > max_id) || (cmd->lun > 7)) return(0x80);
return 0x80;
/* Get pointer to selected device. */
dev = &SCSIDevices[cmd->id][cmd->lun];
dev->InitLength = 0;
if (! scsi_device_present(cmd->id, cmd->lun)) {
cmd_log("BIOS Target ID %i and LUN %i have no device attached\n",
cmd->id, cmd->lun);
return(0x80);
} }
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 0; dma_address = ADDR_TO_U32(cmd->dma_address);
if (!scsi_device_present(BiosCmd->id, BiosCmd->lun)) cmd_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n",
{ sector_len, dma_address);
scsi_bios_command_log("BIOS Target ID %i and LUN %i have no device attached\n",BiosCmd->id,BiosCmd->lun);
return 0x80; if (dev->CmdBuffer != NULL) {
free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
} }
dma_address = ADDR_TO_U32(BiosCmd->dma_address); block_shift = scsi_device_block_shift(cmd->id, cmd->lun);
scsi_bios_command_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", sector_len, dma_address); switch(cmd->command) {
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
{
free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
}
block_shift = scsi_device_block_shift(BiosCmd->id, BiosCmd->lun);
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 */
return 0; return(0);
case 0x01: /* Read Status of Last Operation */ case 0x01: /* Read Status of Last Operation */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
/* Assuming 14 bytes because that's the default length for SCSI sense, and no command-specific /*
indication is given. */ * Assuming 14 bytes because that is the default
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 14; * length for SCSI sense, and no command-specific
* indication is given.
*/
dev->InitLength = 14;
dev->CmdBuffer = (uint8_t *)malloc(14);
memset(dev->CmdBuffer, 0x00, 14);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(14); #if 0
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 14); SCSIStatus = scsi_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION;
#endif
/* SCSIStatus = scsi_bios_command_08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION; */ if (sector_len > 0) {
cmd_log("BIOS DMA: Reading 14 bytes at %08X\n",
if (sector_len > 0) dma_address);
{ DMAPageWrite(dma_address,
scsi_bios_command_log("BusLogic BIOS DMA: Reading 14 bytes at %08X\n", dma_address); (char *)scsi_device_sense(cmd->id, cmd->lun), 14);
DMAPageWrite(dma_address, (char *)scsi_device_sense(BiosCmd->id, BiosCmd->lun), 14);
} }
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) if (dev->CmdBuffer != NULL) {
{ free(dev->CmdBuffer);
free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); dev->CmdBuffer = NULL;
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
} }
return 0; return(0);
break;
case 0x02: /* Read Desired Sectors to Memory */ case 0x02: /* Read Desired Sectors to Memory */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift; dev->InitLength = sector_len << block_shift;
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(sector_len << block_shift); memset(dev->CmdBuffer, 0x00, dev->InitLength);
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[1] = (cmd->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;
@@ -239,43 +265,40 @@ uint8_t scsi_bios_command(uint8_t last_id, BIOSCMD *BiosCmd, int8_t islba)
cdb[7] = (sector_len >> 8) & 0xff; cdb[7] = (sector_len >> 8) & 0xff;
cdb[8] = sector_len & 0xff; cdb[8] = sector_len & 0xff;
#if 0 #if 0
pclog("BIOS CMD(READ, %08lx, %d)\n", lba, BiosCmd->secount); cmd_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount);
#endif #endif
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
if (sector_len > 0) {
if (sector_len > 0) cmd_log("BIOS DMA: Reading %i bytes at %08X\n",
{ dev->InitLength, dma_address);
scsi_bios_command_log("BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); DMAPageWrite(dma_address,
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, sector_len << block_shift); (char *)dev->CmdBuffer, dev->InitLength);
} }
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) if (dev->CmdBuffer != NULL) {
{ free(dev->CmdBuffer);
free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); dev->CmdBuffer = NULL;
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
} }
return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
break;
case 0x03: /* Write Desired Sectors from Memory */ case 0x03: /* Write Desired Sectors from Memory */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift; dev->InitLength = sector_len << block_shift;
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
memset(dev->CmdBuffer, 0x00, dev->InitLength);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(sector_len << block_shift); if (sector_len > 0) {
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, sector_len << block_shift); cmd_log("BIOS DMA: Reading %i bytes at %08X\n",
dev->InitLength, dma_address);
if (sector_len > 0) DMAPageRead(dma_address,
{ (char *)dev->CmdBuffer, dev->InitLength);
scsi_bios_command_log("BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address);
DMAPageRead(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, sector_len << block_shift);
} }
cdb[0] = GPCMD_WRITE_10; cdb[0] = GPCMD_WRITE_10;
cdb[1] = (BiosCmd->lun & 7) << 5; cdb[1] = (cmd->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;
@@ -283,26 +306,23 @@ pclog("BIOS CMD(READ, %08lx, %d)\n", lba, BiosCmd->secount);
cdb[7] = (sector_len >> 8) & 0xff; cdb[7] = (sector_len >> 8) & 0xff;
cdb[8] = sector_len & 0xff; cdb[8] = sector_len & 0xff;
#if 0 #if 0
pclog("BIOS CMD(WRITE, %08lx, %d)\n", lba, BiosCmd->secount); cmd_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount);
#endif #endif
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) if (dev->CmdBuffer != NULL) {
{ free(dev->CmdBuffer);
free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); dev->CmdBuffer = NULL;
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
} }
return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
break;
case 0x04: /* Verify Desired Sectors */ case 0x04: /* Verify Desired Sectors */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
cdb[0] = GPCMD_VERIFY_10; cdb[0] = GPCMD_VERIFY_10;
cdb[1] = (BiosCmd->lun & 7) << 5; cdb[1] = (cmd->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;
@@ -310,143 +330,121 @@ pclog("BIOS CMD(WRITE, %08lx, %d)\n", lba, BiosCmd->secount);
cdb[7] = (sector_len >> 8) & 0xff; cdb[7] = (sector_len >> 8) & 0xff;
cdb[8] = sector_len & 0xff; cdb[8] = sector_len & 0xff;
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
break;
case 0x05: /* Format Track, invalid since SCSI has no tracks */ case 0x05: /* Format Track, invalid since SCSI has no tracks */
return 1; //FIXME: add a longer delay here --FvK
return(1);
break;
case 0x06: /* Identify SCSI Devices, in practice it's a nop */ case 0x06: /* Identify SCSI Devices, in practice it's a nop */
return 0; //FIXME: add a longer delay here --FvK
return(0);
break;
case 0x07: /* Format Unit */ case 0x07: /* Format Unit */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
cdb[0] = GPCMD_FORMAT_UNIT; cdb[0] = GPCMD_FORMAT_UNIT;
cdb[1] = (BiosCmd->lun & 7) << 5; cdb[1] = (cmd->lun & 7) << 5;
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
break;
case 0x08: /* Read Drive Parameters */ case 0x08: /* Read Drive Parameters */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6; dev->InitLength = 6;
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
memset(dev->CmdBuffer, 0x00, dev->InitLength);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6); ret = scsi_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer);
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6);
ret = scsi_bios_command_08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
DMAPageWrite(dma_address,
(char *)dev->CmdBuffer, dev->InitLength);
scsi_bios_command_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); if (dev->CmdBuffer != NULL) {
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6); free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
{
free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
} }
return ret; return(ret);
break;
case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */ case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */
return 0; //FIXME: add a longer delay here --FvK
return(0);
break; case 0x0c: /* Seek */
target_check(cmd->id, cmd->lun);
case 0x0C: /* Seek */ //FIXME: is this needed? Looks like a copy-paste leftover.. --FvK
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); dev->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[1] = (cmd->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;
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
return (SCSIStatus == SCSI_STATUS_OK) ? 1 : 0; return((SCSIStatus == SCSI_STATUS_OK) ? 1 : 0);
break; case 0x0d: /* Alternate Disk Reset, in practice it's a nop */
//FIXME: add a longer delay here --FvK
case 0x0D: /* Alternate Disk Reset, in practice it's a nop */ return(0);
return 0;
break;
case 0x10: /* Test Drive Ready */ case 0x10: /* Test Drive Ready */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
cdb[0] = GPCMD_TEST_UNIT_READY; cdb[0] = GPCMD_TEST_UNIT_READY;
cdb[1] = (BiosCmd->lun & 7) << 5; cdb[1] = (cmd->lun & 7) << 5;
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
break;
case 0x11: /* Recalibrate */ case 0x11: /* Recalibrate */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
cdb[0] = GPCMD_REZERO_UNIT; cdb[0] = GPCMD_REZERO_UNIT;
cdb[1] = (BiosCmd->lun & 7) << 5; cdb[1] = (cmd->lun & 7) << 5;
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); scsi_device_command(cmd->id, cmd->lun, 12, cdb);
return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); return(completion_code(scsi_device_sense(cmd->id, cmd->lun)));
break;
case 0x14: /* Controller Diagnostic */ case 0x14: /* Controller Diagnostic */
return 0; //FIXME: add a longer delay here --FvK
return(0);
break;
case 0x15: /* Read DASD Type */ case 0x15: /* Read DASD Type */
scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); target_check(cmd->id, cmd->lun);
SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6; dev->InitLength = 6;
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
memset(dev->CmdBuffer, 0x00, dev->InitLength);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6); ret = scsi_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer);
memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6);
ret = scsi_bios_command_15(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
DMAPageWrite(dma_address,
(char *)dev->CmdBuffer, dev->InitLength);
scsi_bios_command_log("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address); if (dev->CmdBuffer != NULL) {
DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6); free(dev->CmdBuffer);
dev->CmdBuffer = NULL;
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
{
free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer);
SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL;
} }
return ret; return(ret);
break;
default: default:
scsi_bios_command_log("BusLogic BIOS: Unimplemented command: %02X\n", BiosCmd->command); cmd_log("BIOS: Unimplemented command: %02X\n", cmd->command);
return 1; return(1);
break;
} }
pclog("BIOS Request complete\n"); cmd_log("BIOS Request complete\n");
} }