The AHA-154x code is now converted to use the abstraction layer;
Moved SCSI device array building to scsi_card_init() in scsi.c.
This commit is contained in:
37
src/scsi.c
37
src/scsi.c
@@ -8,13 +8,14 @@
|
|||||||
*
|
*
|
||||||
* Handling of the SCSI controllers.
|
* Handling of the SCSI controllers.
|
||||||
*
|
*
|
||||||
* NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go.
|
* Version: @(#)scsi.c 1.0.1 2017/08/22
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi.c 1.0.0 2017/06/14
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
*
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
* Original Buslogic version by SA1988 and Miran Grca.
|
* Copyright 2008-2017 TheCollector1995.
|
||||||
* Copyright 2017 Fred N. van Kempen.
|
* Copyright 2016-2017 Miran Grca.
|
||||||
|
* Copyright 2017-2017 Fred N. van Kempen.
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -108,6 +109,30 @@ int scsi_card_get_from_internal_name(char *s)
|
|||||||
|
|
||||||
void scsi_card_init()
|
void scsi_card_init()
|
||||||
{
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
pclog("Building SCSI hard disk map...\n");
|
||||||
|
build_scsi_hd_map();
|
||||||
|
pclog("Building SCSI CD-ROM map...\n");
|
||||||
|
build_scsi_cdrom_map();
|
||||||
|
|
||||||
|
for (i=0; i<16; i++)
|
||||||
|
{
|
||||||
|
for (j=0; j<8; j++)
|
||||||
|
{
|
||||||
|
if (scsi_hard_disks[i][j] != 0xff) {
|
||||||
|
SCSIDevices[i][j].LunType = SCSI_DISK;
|
||||||
|
}
|
||||||
|
else if (scsi_cdrom_drives[i][j] != 0xff) {
|
||||||
|
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCSIDevices[i][j].LunType = SCSI_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (scsi_cards[scsi_card_current].device)
|
if (scsi_cards[scsi_card_current].device)
|
||||||
device_add(scsi_cards[scsi_card_current].device);
|
device_add(scsi_cards[scsi_card_current].device);
|
||||||
|
|
||||||
|
|||||||
20
src/scsi.h
20
src/scsi.h
@@ -1,5 +1,21 @@
|
|||||||
/* Copyright holders: SA1988
|
/*
|
||||||
see COPYING for more details
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
|
* running old operating systems and software designed for IBM
|
||||||
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
|
* system designs based on the PCI bus.
|
||||||
|
*
|
||||||
|
* This file is part of the 86Box distribution.
|
||||||
|
*
|
||||||
|
* SCSI controller handler header.
|
||||||
|
*
|
||||||
|
* Version: @(#)scsi_h 1.0.0 2017/08/22
|
||||||
|
*
|
||||||
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
|
* Copyright 2008-2017 TheCollector1995.
|
||||||
|
* Copyright 2016-2017 Miran Grca.
|
||||||
|
* Copyright 2017-2017 Fred N. van Kempen.
|
||||||
*/
|
*/
|
||||||
#ifndef SCSI_H
|
#ifndef SCSI_H
|
||||||
#define SCSI_H
|
#define SCSI_H
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
* NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go.
|
* NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_aha154x.c 1.0.9 2017/08/16
|
* Version: @(#)scsi_aha154x.c 1.0.10 2017/08/22
|
||||||
*
|
*
|
||||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
* Original Buslogic version by SA1988 and Miran Grca.
|
* Original Buslogic version by SA1988 and Miran Grca.
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
|
#include "scsi_device.h"
|
||||||
#include "scsi_disk.h"
|
#include "scsi_disk.h"
|
||||||
#include "scsi_aha154x.h"
|
#include "scsi_aha154x.h"
|
||||||
|
|
||||||
@@ -1217,7 +1218,7 @@ aha_0x01:
|
|||||||
for (i=0; i<7; i++) {
|
for (i=0; i<7; i++) {
|
||||||
dev->DataBuf[i] = 0x00;
|
dev->DataBuf[i] = 0x00;
|
||||||
for (j=0; j<8; j++) {
|
for (j=0; j<8; j++) {
|
||||||
if (SCSIDevices[i][j].LunType != SCSI_NONE)
|
if (scsi_device_present(i, j))
|
||||||
dev->DataBuf[i] |= (1<<j);
|
dev->DataBuf[i] |= (1<<j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1389,23 +1390,14 @@ ConvertSenseLength(uint8_t RequestSenseLength)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SenseBufferFree(Req_t *req, int Copy, int is_hd)
|
SenseBufferFree(Req_t *req, int Copy)
|
||||||
{
|
{
|
||||||
uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
|
uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
|
||||||
uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN];
|
|
||||||
uint8_t hdc_id = scsi_hard_disks[req->TargetID][req->LUN];
|
|
||||||
uint32_t SenseBufferAddress;
|
uint32_t SenseBufferAddress;
|
||||||
uint8_t temp_sense[256];
|
uint8_t temp_sense[256];
|
||||||
|
|
||||||
if (SenseLength && Copy) {
|
if (SenseLength && Copy) {
|
||||||
if (is_hd)
|
scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength);
|
||||||
{
|
|
||||||
scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sense address, in 32-bit mode, is located in the
|
* The sense address, in 32-bit mode, is located in the
|
||||||
@@ -1431,165 +1423,43 @@ SenseBufferFree(Req_t *req, int Copy, int is_hd)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aha_disk_cmd(aha_t *dev)
|
aha_scsi_cmd(aha_t *dev)
|
||||||
{
|
{
|
||||||
Req_t *req = &dev->Req;
|
Req_t *req = &dev->Req;
|
||||||
uint8_t Id, Lun;
|
uint8_t Id, Lun;
|
||||||
uint8_t hdc_id;
|
|
||||||
uint8_t hd_phase;
|
|
||||||
uint8_t temp_cdb[12];
|
uint8_t temp_cdb[12];
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
int target_cdb_len = 12;
|
||||||
|
|
||||||
Id = req->TargetID;
|
Id = req->TargetID;
|
||||||
Lun = req->LUN;
|
Lun = req->LUN;
|
||||||
hdc_id = scsi_hard_disks[Id][Lun];
|
|
||||||
|
|
||||||
if (hdc_id == 0xff) fatal("SCSI hard disk on %02i:%02i has disappeared\n", Id, Lun);
|
target_cdb_len = scsi_device_cdb_length(Id, Lun);
|
||||||
|
|
||||||
pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n",
|
if (!scsi_device_valid(Id, Lun))
|
||||||
Id, Lun, hdc_id);
|
fatal("SCSI target on %02i:%02i has disappeared\n", Id, Lun);
|
||||||
|
|
||||||
|
pclog("SCSI 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++) {
|
||||||
pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]);
|
pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(temp_cdb, 0x00, 12);
|
memset(temp_cdb, 0, target_cdb_len);
|
||||||
if (req->CmdBlock.common.CdbLength <= 12) {
|
if (req->CmdBlock.common.CdbLength <= target_cdb_len) {
|
||||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb,
|
memcpy(temp_cdb, req->CmdBlock.common.Cdb,
|
||||||
req->CmdBlock.common.CdbLength);
|
req->CmdBlock.common.CdbLength);
|
||||||
} else {
|
} else {
|
||||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, 12);
|
memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
scsi_device_command(Id, Lun, req->CmdBlock.common.CdbLength, temp_cdb);
|
||||||
* Since that field in the HDC struct is never used when
|
|
||||||
* the bus type is SCSI, let's use it for this scope.
|
|
||||||
*/
|
|
||||||
shdc[hdc_id].request_length = temp_cdb[1];
|
|
||||||
|
|
||||||
if (req->CmdBlock.common.CdbLength != 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.
|
|
||||||
*/
|
|
||||||
temp_cdb[1] &= 0x1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
|
||||||
SCSIPhase = SCSI_PHASE_COMMAND;
|
|
||||||
scsi_hd_command(hdc_id, temp_cdb);
|
|
||||||
SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id);
|
|
||||||
if (SCSIStatus == SCSI_STATUS_OK) {
|
|
||||||
hd_phase = scsi_hd_phase_to_scsi(hdc_id);
|
|
||||||
if (hd_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", shdc[hdc_id].sense[2], shdc[hdc_id].sense[12], shdc[hdc_id].sense[13]);
|
|
||||||
|
|
||||||
aha_buf_free(req);
|
aha_buf_free(req);
|
||||||
|
|
||||||
SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 1);
|
SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK));
|
||||||
|
|
||||||
pclog("Request complete\n");
|
|
||||||
|
|
||||||
if (SCSIStatus == SCSI_STATUS_OK) {
|
|
||||||
aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
|
||||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
|
||||||
} else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) {
|
|
||||||
aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
|
||||||
CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
aha_cdrom_cmd(aha_t *dev)
|
|
||||||
{
|
|
||||||
Req_t *req = &dev->Req;
|
|
||||||
uint8_t Id, Lun;
|
|
||||||
uint8_t cdrom_id;
|
|
||||||
uint8_t cdrom_phase;
|
|
||||||
uint8_t temp_cdb[12];
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
Id = req->TargetID;
|
|
||||||
Lun = req->LUN;
|
|
||||||
cdrom_id = scsi_cdrom_drives[Id][Lun];
|
|
||||||
|
|
||||||
if (cdrom_id == 0xff)
|
|
||||||
fatal("SCSI CD-ROM on %02i:%02i has disappeared\n", Id, Lun);
|
|
||||||
|
|
||||||
pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n",
|
|
||||||
Id, Lun, cdrom_id);
|
|
||||||
|
|
||||||
pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]);
|
|
||||||
for (i = 1; i<req->CmdBlock.common.CdbLength; i++) {
|
|
||||||
pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len);
|
|
||||||
if (req->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) {
|
|
||||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb,
|
|
||||||
req->CmdBlock.common.CdbLength);
|
|
||||||
} else {
|
|
||||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since that field in the CDROM struct is never used when
|
|
||||||
* the bus type is SCSI, let's use it for this scope.
|
|
||||||
*/
|
|
||||||
cdrom[cdrom_id].request_length = temp_cdb[1];
|
|
||||||
|
|
||||||
if (req->CmdBlock.common.CdbLength != 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.
|
|
||||||
*/
|
|
||||||
temp_cdb[1] &= 0x1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
|
||||||
SCSIPhase = SCSI_PHASE_COMMAND;
|
|
||||||
cdrom_command(cdrom_id, temp_cdb);
|
|
||||||
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id);
|
|
||||||
if (SCSIStatus == SCSI_STATUS_OK) {
|
|
||||||
cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id);
|
|
||||||
if (cdrom_phase == 2) {
|
|
||||||
/* Command completed - call the phase callback to complete the command. */
|
|
||||||
cdrom_phase_callback(cdrom_id);
|
|
||||||
} else {
|
|
||||||
/* Command first phase complete - call the callback to execute the second phase. */
|
|
||||||
cdrom_phase_callback(cdrom_id);
|
|
||||||
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id);
|
|
||||||
/* Command second phase complete - call the callback to complete the command. */
|
|
||||||
cdrom_phase_callback(cdrom_id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Error (Check Condition) - call the phase callback to complete the command. */
|
|
||||||
cdrom_phase_callback(cdrom_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]);
|
|
||||||
|
|
||||||
aha_buf_free(req);
|
|
||||||
|
|
||||||
SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0);
|
|
||||||
|
|
||||||
pclog("Request complete\n");
|
pclog("Request complete\n");
|
||||||
|
|
||||||
@@ -1633,10 +1503,10 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
|||||||
|
|
||||||
aha_buf_alloc(req, req->Is24bit);
|
aha_buf_alloc(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);
|
||||||
aha_buf_free(req);
|
aha_buf_free(req);
|
||||||
SenseBufferFree(req, 0, 0);
|
SenseBufferFree(req, 0);
|
||||||
aha_mbi_setup(dev, CCBPointer, &req->CmdBlock,
|
aha_mbi_setup(dev, CCBPointer, &req->CmdBlock,
|
||||||
CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR);
|
CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR);
|
||||||
} else {
|
} else {
|
||||||
@@ -1650,8 +1520,7 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
|||||||
req->CmdBlock.common.ControlByte);
|
req->CmdBlock.common.ControlByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
AHA_InOperation = (SCSIDevices[Id][Lun].LunType == SCSI_DISK) ? 0x11 : 1;
|
AHA_InOperation = 1;
|
||||||
pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1778,8 +1647,8 @@ aha_cmd_cb(void *priv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (AHA_InOperation == 1) {
|
} else if (AHA_InOperation == 1) {
|
||||||
pclog("%s: Callback: Process CD-ROM request\n", dev->name);
|
pclog("%s: Callback: Process SCSI request\n", dev->name);
|
||||||
aha_cdrom_cmd(dev);
|
aha_scsi_cmd(dev);
|
||||||
aha_mbi(dev);
|
aha_mbi(dev);
|
||||||
if (dev->Req.CmdBlock.common.Cdb[0] == 0x42) {
|
if (dev->Req.CmdBlock.common.Cdb[0] == 0x42) {
|
||||||
/* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */
|
/* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */
|
||||||
@@ -1789,10 +1658,6 @@ aha_cmd_cb(void *priv)
|
|||||||
} else if (AHA_InOperation == 2) {
|
} else if (AHA_InOperation == 2) {
|
||||||
pclog("%s: Callback: Send incoming mailbox\n", dev->name);
|
pclog("%s: Callback: Send incoming mailbox\n", dev->name);
|
||||||
aha_mbi(dev);
|
aha_mbi(dev);
|
||||||
} else if (AHA_InOperation == 0x11) {
|
|
||||||
pclog("%s: Callback: Process DISK request\n", dev->name);
|
|
||||||
aha_disk_cmd(dev);
|
|
||||||
aha_mbi(dev);
|
|
||||||
} else {
|
} else {
|
||||||
fatal("%s: Invalid callback phase: %i\n", dev->name, AHA_InOperation);
|
fatal("%s: Invalid callback phase: %i\n", dev->name, AHA_InOperation);
|
||||||
}
|
}
|
||||||
@@ -2060,7 +1925,6 @@ static void *
|
|||||||
aha_init(int type)
|
aha_init(int type)
|
||||||
{
|
{
|
||||||
aha_t *dev;
|
aha_t *dev;
|
||||||
int i, j;
|
|
||||||
uint32_t bios_addr = 0x00000000;
|
uint32_t bios_addr = 0x00000000;
|
||||||
int bios = 0;
|
int bios = 0;
|
||||||
|
|
||||||
@@ -2138,22 +2002,6 @@ aha_init(int type)
|
|||||||
}
|
}
|
||||||
ResetDev = dev;
|
ResetDev = dev;
|
||||||
|
|
||||||
pclog("Building SCSI hard disk map...\n");
|
|
||||||
build_scsi_hd_map();
|
|
||||||
pclog("Building SCSI CD-ROM map...\n");
|
|
||||||
build_scsi_cdrom_map();
|
|
||||||
for (i=0; i<16; i++) {
|
|
||||||
for (j=0; j<8; j++) {
|
|
||||||
if (scsi_hard_disks[i][j] != 0xff) {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_DISK;
|
|
||||||
} else if (find_cdrom_for_scsi_id(i, j) != 0xff) {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
|
||||||
} else {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev);
|
timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev);
|
||||||
timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev);
|
timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev);
|
||||||
|
|
||||||
@@ -2200,7 +2048,6 @@ static void *
|
|||||||
aha_1640_init(void)
|
aha_1640_init(void)
|
||||||
{
|
{
|
||||||
aha_t *dev;
|
aha_t *dev;
|
||||||
int i, j;
|
|
||||||
|
|
||||||
dev = malloc(sizeof(aha_t));
|
dev = malloc(sizeof(aha_t));
|
||||||
memset(dev, 0x00, sizeof(aha_t));
|
memset(dev, 0x00, sizeof(aha_t));
|
||||||
@@ -2213,24 +2060,6 @@ aha_1640_init(void)
|
|||||||
|
|
||||||
ResetDev = dev;
|
ResetDev = dev;
|
||||||
|
|
||||||
pclog("Building SCSI hard disk map...\n");
|
|
||||||
build_scsi_hd_map();
|
|
||||||
pclog("Building SCSI CD-ROM map...\n");
|
|
||||||
build_scsi_cdrom_map();
|
|
||||||
for (i=0; i<16; i++) {
|
|
||||||
for (j=0; j<8; j++) {
|
|
||||||
if (scsi_hard_disks[i][j] != 0xff) {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_DISK;
|
|
||||||
}
|
|
||||||
else if (find_cdrom_for_scsi_id(i, j) != 0xff) {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev);
|
timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev);
|
||||||
timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev);
|
timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* 0 - BT-542B ISA;
|
* 0 - BT-542B ISA;
|
||||||
* 1 - BT-958 PCI (but BT-542B ISA on non-PCI machines)
|
* 1 - BT-958 PCI (but BT-542B ISA on non-PCI machines)
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_buslogic.c 1.0.6 2017/08/17
|
* Version: @(#)scsi_buslogic.c 1.0.7 2017/08/22
|
||||||
*
|
*
|
||||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -1163,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_device_command(ESCSICmd->CDBLength, ESCSICmd->TargetId, ESCSICmd->LogicalUnit, temp_cdb);
|
scsi_device_command(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->CDBLength, 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); */
|
||||||
@@ -1372,7 +1372,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;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
if (sector_len > 0)
|
if (sector_len > 0)
|
||||||
{
|
{
|
||||||
@@ -1413,7 +1413,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;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
|
if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL)
|
||||||
{
|
{
|
||||||
@@ -1437,7 +1437,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;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
@@ -1459,7 +1459,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[0] = GPCMD_FORMAT_UNIT;
|
cdb[0] = GPCMD_FORMAT_UNIT;
|
||||||
cdb[1] = (BiosCmd->lun & 7) << 5;
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
@@ -1505,7 +1505,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[4] = (lba >> 8) & 0xff;
|
cdb[4] = (lba >> 8) & 0xff;
|
||||||
cdb[5] = lba & 0xff;
|
cdb[5] = lba & 0xff;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
return (SCSIStatus == SCSI_STATUS_OK) ? 1 : 0;
|
return (SCSIStatus == SCSI_STATUS_OK) ? 1 : 0;
|
||||||
|
|
||||||
@@ -1522,7 +1522,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[0] = GPCMD_TEST_UNIT_READY;
|
cdb[0] = GPCMD_TEST_UNIT_READY;
|
||||||
cdb[1] = (BiosCmd->lun & 7) << 5;
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
@@ -1534,7 +1534,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd)
|
|||||||
cdb[0] = GPCMD_REZERO_UNIT;
|
cdb[0] = GPCMD_REZERO_UNIT;
|
||||||
cdb[1] = (BiosCmd->lun & 7) << 5;
|
cdb[1] = (BiosCmd->lun & 7) << 5;
|
||||||
|
|
||||||
scsi_device_command(12, BiosCmd->id, BiosCmd->lun, cdb);
|
scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb);
|
||||||
|
|
||||||
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
return BuslogicCompletionCode(scsi_device_sense(BiosCmd->id, BiosCmd->lun));
|
||||||
|
|
||||||
@@ -2278,23 +2278,14 @@ BuslogicWriteL(uint16_t Port, uint32_t Val, void *p)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
BuslogicSenseBufferFree(Req_t *req, int Copy, int is_hd)
|
BuslogicSenseBufferFree(Req_t *req, int Copy)
|
||||||
{
|
{
|
||||||
uint8_t SenseLength = BuslogicConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
|
uint8_t SenseLength = BuslogicConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
|
||||||
uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN];
|
|
||||||
uint8_t hdc_id = scsi_hard_disks[req->TargetID][req->LUN];
|
|
||||||
uint32_t SenseBufferAddress;
|
uint32_t SenseBufferAddress;
|
||||||
uint8_t temp_sense[256];
|
uint8_t temp_sense[256];
|
||||||
|
|
||||||
if (SenseLength && Copy) {
|
if (SenseLength && Copy) {
|
||||||
if (is_hd)
|
scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength);
|
||||||
{
|
|
||||||
scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sense address, in 32-bit mode, is located in the
|
* The sense address, in 32-bit mode, is located in the
|
||||||
@@ -2350,11 +2341,11 @@ 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_device_command(req->CmdBlock.common.CdbLength, Id, Lun, temp_cdb);
|
scsi_device_command(Id, Lun, req->CmdBlock.common.CdbLength, temp_cdb);
|
||||||
|
|
||||||
BuslogicDataBufferFree(req);
|
BuslogicDataBufferFree(req);
|
||||||
|
|
||||||
BuslogicSenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0);
|
BuslogicSenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK));
|
||||||
|
|
||||||
pclog("Request complete\n");
|
pclog("Request complete\n");
|
||||||
|
|
||||||
@@ -2400,7 +2391,7 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb
|
|||||||
if (!scsi_device_present(Id, Lun)) {
|
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);
|
||||||
BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock,
|
BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock,
|
||||||
CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR);
|
CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR);
|
||||||
} else {
|
} else {
|
||||||
@@ -2838,9 +2829,6 @@ BuslogicInit(int chip)
|
|||||||
{
|
{
|
||||||
Buslogic_t *bl;
|
Buslogic_t *bl;
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
bl = malloc(sizeof(Buslogic_t));
|
bl = malloc(sizeof(Buslogic_t));
|
||||||
memset(bl, 0x00, sizeof(Buslogic_t));
|
memset(bl, 0x00, sizeof(Buslogic_t));
|
||||||
|
|
||||||
@@ -2894,28 +2882,6 @@ BuslogicInit(int chip)
|
|||||||
bl->bios_mask = 0;
|
bl->bios_mask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pclog("Building SCSI hard disk map...\n");
|
|
||||||
build_scsi_hd_map();
|
|
||||||
pclog("Building SCSI CD-ROM map...\n");
|
|
||||||
build_scsi_cdrom_map();
|
|
||||||
|
|
||||||
for (i=0; i<16; i++)
|
|
||||||
{
|
|
||||||
for (j=0; j<8; j++)
|
|
||||||
{
|
|
||||||
if (scsi_hard_disks[i][j] != 0xff) {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_DISK;
|
|
||||||
}
|
|
||||||
else if (find_cdrom_for_scsi_id(i, j) != 0xff) {
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SCSIDevices[i][j].LunType = SCSI_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_add(BuslogicResetPoll,
|
timer_add(BuslogicResetPoll,
|
||||||
&BuslogicResetCallback, &BuslogicResetCallback, bl);
|
&BuslogicResetCallback, &BuslogicResetCallback, bl);
|
||||||
timer_add(BuslogicCommandCallback,
|
timer_add(BuslogicCommandCallback,
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
|
* running old operating systems and software designed for IBM
|
||||||
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
|
* system designs based on the PCI bus.
|
||||||
|
*
|
||||||
|
* This file is part of the 86Box distribution.
|
||||||
|
*
|
||||||
|
* The generic SCSI device command handler.
|
||||||
|
*
|
||||||
|
* Version: @(#)scsi_device.c 1.0.0 2017/08/22
|
||||||
|
*
|
||||||
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||||
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
|
* Copyright 2016-2017 Miran Grca.
|
||||||
|
* Copyright 2017-2017 Fred N. van Kempen.
|
||||||
|
*/
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include "scsi_disk.h"
|
#include "scsi_disk.h"
|
||||||
@@ -119,6 +136,29 @@ uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
scsi_hd_request_sense_for_scsi(id, buffer, alloc_length);
|
||||||
|
break;
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||||
|
cdrom_request_sense_for_scsi(id, buffer, alloc_length);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
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 lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
@@ -231,7 +271,7 @@ 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)
|
void scsi_device_command(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb)
|
||||||
{
|
{
|
||||||
uint8_t phase = 0;
|
uint8_t phase = 0;
|
||||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Definitions for the generic SCSI device command handler.
|
* Definitions for the generic SCSI device command handler.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_devic3.h 1.0.1 2017/08/21
|
* Version: @(#)scsi_device.h 1.0.2 2017/08/22
|
||||||
*
|
*
|
||||||
* 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>
|
||||||
@@ -20,6 +20,9 @@
|
|||||||
extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun);
|
extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun);
|
||||||
extern void scsi_device_type_data(uint8_t id, uint8_t lun,
|
extern void scsi_device_type_data(uint8_t id, uint8_t lun,
|
||||||
uint8_t *type, uint8_t *rmb);
|
uint8_t *type, uint8_t *rmb);
|
||||||
|
extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint8_t alloc_length);
|
||||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t lun,
|
extern int scsi_device_read_capacity(uint8_t id, uint8_t lun,
|
||||||
uint8_t *cdb, uint8_t *buffer,
|
uint8_t *cdb, uint8_t *buffer,
|
||||||
uint32_t *len);
|
uint32_t *len);
|
||||||
@@ -27,7 +30,7 @@ extern int scsi_device_present(uint8_t id, uint8_t lun);
|
|||||||
extern int scsi_device_valid(uint8_t id, uint8_t lun);
|
extern int scsi_device_valid(uint8_t id, uint8_t lun);
|
||||||
extern int scsi_device_cdb_length(uint8_t id, uint8_t lun);
|
extern int scsi_device_cdb_length(uint8_t id, uint8_t lun);
|
||||||
extern int scsi_device_block_shift(uint8_t id, uint8_t lun);
|
extern int scsi_device_block_shift(uint8_t id, uint8_t lun);
|
||||||
extern void scsi_device_command(int cdb_len, uint8_t id, uint8_t lun,
|
extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len,
|
||||||
uint8_t *cdb);
|
uint8_t *cdb);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user