Split generic CD-ROM from SCSI-style CD-ROM;
Redid the way SCSI and ATAPI devices are handled; Slight timings change in the NCR 5380; Devices are now closed by device_close_all() in the reverse order of the one in which they were started; Slight changes to some code in win/; Added the WM_HARDRESET and WM_SHUTDOWN window messages for configuration manager purposes.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the SCSI controllers.
|
||||
*
|
||||
* Version: @(#)scsi.c 1.0.21 2018/10/02
|
||||
* Version: @(#)scsi.c 1.0.22 2018/10/10
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -43,15 +43,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
char scsi_fn[SCSI_NUM][512];
|
||||
uint16_t scsi_disk_location[SCSI_NUM];
|
||||
|
||||
int scsi_card_current = 0;
|
||||
int scsi_card_last = 0;
|
||||
|
||||
uint32_t SCSI_BufferLength;
|
||||
|
||||
|
||||
typedef const struct {
|
||||
const char *name;
|
||||
@@ -83,26 +77,6 @@ static SCSI_CARD scsi_cards[] = {
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_SCSI_LOG
|
||||
int scsi_do_log = ENABLE_SCSI_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
scsi_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_SCSI_LOG
|
||||
va_list ap;
|
||||
|
||||
if (scsi_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int scsi_card_available(int card)
|
||||
{
|
||||
if (scsi_cards[card].device)
|
||||
@@ -159,25 +133,13 @@ void scsi_card_init(void)
|
||||
if (!scsi_cards[scsi_card_current].device)
|
||||
return;
|
||||
|
||||
scsi_log("Building SCSI hard disk map...\n");
|
||||
build_scsi_disk_map();
|
||||
scsi_log("Building SCSI CD-ROM map...\n");
|
||||
build_scsi_cdrom_map();
|
||||
scsi_log("Building SCSI ZIP map...\n");
|
||||
build_scsi_zip_map();
|
||||
for (i = 0; i < SCSI_ID_MAX; i++) {
|
||||
if (scsi_devices[i].cmd_buffer)
|
||||
free(scsi_devices[i].cmd_buffer);
|
||||
scsi_devices[i].cmd_buffer = NULL;
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
if (scsi_disks[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_DISK;
|
||||
else if (scsi_cdrom_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_CDROM;
|
||||
else if (scsi_zip_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[i].LunType = SCSI_NONE;
|
||||
if (SCSIDevices[i].CmdBuffer)
|
||||
free(SCSIDevices[i].CmdBuffer);
|
||||
SCSIDevices[i].CmdBuffer = NULL;
|
||||
memset(&scsi_devices[i], 0, sizeof(scsi_device_t));
|
||||
scsi_devices[i].type = SCSI_NONE;
|
||||
}
|
||||
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* 1 - BT-545S ISA;
|
||||
* 2 - BT-958D PCI
|
||||
*
|
||||
* Version: @(#)scsi_buslogic.c 1.0.39 2018/06/11
|
||||
* Version: @(#)scsi_buslogic.c 1.0.40 2018/10/09
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -556,6 +556,7 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
|
||||
int DataLength = ESCSICmd->DataLength;
|
||||
uint32_t Address;
|
||||
uint32_t TransferLength;
|
||||
scsi_device_t *dev = &scsi_devices[TargetID];
|
||||
|
||||
if (ESCSICmd->DataDirection == 0x03) {
|
||||
/* Non-data command. */
|
||||
@@ -567,16 +568,16 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
|
||||
|
||||
/* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
|
||||
checking its length, so do this procedure for both read/write commands. */
|
||||
if ((DataLength > 0) && (SCSIDevices[TargetID].BufferLength > 0)) {
|
||||
if ((DataLength > 0) && (dev->buffer_length > 0)) {
|
||||
Address = DataPointer;
|
||||
TransferLength = MIN(DataLength, SCSIDevices[TargetID].BufferLength);
|
||||
TransferLength = MIN(DataLength, dev->buffer_length);
|
||||
|
||||
if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) {
|
||||
buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address);
|
||||
DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength);
|
||||
DMAPageRead(Address, (uint8_t *)dev->cmd_buffer, TransferLength);
|
||||
} else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) {
|
||||
buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address);
|
||||
DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength);
|
||||
DMAPageWrite(Address, (uint8_t *)dev->cmd_buffer, TransferLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -591,6 +592,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
int target_cdb_len = 12;
|
||||
uint8_t target_id = 0;
|
||||
int phase;
|
||||
scsi_device_t *sd = &scsi_devices[ESCSICmd->TargetId];
|
||||
|
||||
DataInBuf[0] = DataInBuf[1] = 0;
|
||||
|
||||
@@ -602,9 +604,9 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
|
||||
buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId);
|
||||
|
||||
SCSIDevices[ESCSICmd->TargetId].Status = SCSI_STATUS_OK;
|
||||
sd->status = SCSI_STATUS_OK;
|
||||
|
||||
if (!scsi_device_present(ESCSICmd->TargetId)) {
|
||||
if (!scsi_device_present(sd)) {
|
||||
buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId);
|
||||
DataInBuf[2] = CCB_SELECTION_TIMEOUT;
|
||||
DataInBuf[3] = SCSI_STATUS_OK;
|
||||
@@ -623,7 +625,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
|
||||
target_cdb_len = 12;
|
||||
|
||||
if (!scsi_device_valid(ESCSICmd->TargetId)) fatal("SCSI target on ID %02i has disappeared\n", ESCSICmd->TargetId);
|
||||
if (!scsi_device_valid(sd)) fatal("SCSI target on ID %02i has disappeared\n", ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id);
|
||||
|
||||
@@ -639,26 +641,26 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len);
|
||||
}
|
||||
|
||||
SCSIDevices[ESCSICmd->TargetId].BufferLength = ESCSICmd->DataLength;
|
||||
scsi_device_command_phase0(ESCSICmd->TargetId, temp_cdb);
|
||||
sd->buffer_length = ESCSICmd->DataLength;
|
||||
scsi_device_command_phase0(sd, temp_cdb);
|
||||
|
||||
phase = SCSIDevices[ESCSICmd->TargetId].Phase;
|
||||
phase = sd->phase;
|
||||
if (phase != SCSI_PHASE_STATUS) {
|
||||
if (phase == SCSI_PHASE_DATA_IN)
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId);
|
||||
scsi_device_command_phase1(sd);
|
||||
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT));
|
||||
if (phase == SCSI_PHASE_DATA_OUT)
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId);
|
||||
scsi_device_command_phase1(sd);
|
||||
}
|
||||
|
||||
x54x_buf_free(ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("BIOS Request complete\n");
|
||||
|
||||
if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_OK) {
|
||||
if (sd->status == SCSI_STATUS_OK) {
|
||||
DataInBuf[2] = CCB_COMPLETE;
|
||||
DataInBuf[3] = SCSI_STATUS_OK;
|
||||
} else if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
} else if (scsi_devices[ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
DataInBuf[2] = CCB_COMPLETE;
|
||||
DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
@@ -697,15 +699,15 @@ buslogic_cmds(void *p)
|
||||
case 0x23:
|
||||
memset(dev->DataBuf, 0, 8);
|
||||
for (i = 8; i < 15; i++) {
|
||||
dev->DataBuf[i-8] = 0;
|
||||
if (scsi_device_present(i) && (i != buslogic_get_host_id(dev)))
|
||||
dev->DataBuf[i-8] |= 1;
|
||||
dev->DataBuf[i - 8] = 0;
|
||||
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
|
||||
dev->DataBuf[i - 8] |= 1;
|
||||
}
|
||||
dev->DataReplyLeft = 8;
|
||||
break;
|
||||
case 0x24:
|
||||
for (i=0; i<15; i++) {
|
||||
if (scsi_device_present(i) && (i != buslogic_get_host_id(dev)))
|
||||
for (i = 0; i < 15; i++) {
|
||||
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
|
||||
TargetsPresentMask |= (1 << i);
|
||||
}
|
||||
dev->DataBuf[0] = TargetsPresentMask & 0xFF;
|
||||
|
||||
3091
src/scsi/scsi_cdrom.c
Normal file
3091
src/scsi/scsi_cdrom.c
Normal file
File diff suppressed because it is too large
Load Diff
75
src/scsi/scsi_cdrom.h
Normal file
75
src/scsi/scsi_cdrom.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the CD-ROM drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
* Version: @(#)scsi_cdrom.h 1.0.0 2018/10/09
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2018 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_SCSI_CDROM_H
|
||||
#define EMU_SCSI_CDROM_H
|
||||
|
||||
|
||||
#define CDROM_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
|
||||
|
||||
|
||||
#ifdef SCSI_DEVICE_H
|
||||
typedef struct {
|
||||
/* Common block. */
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
cdrom_drive_t *drv;
|
||||
|
||||
uint8_t *buffer,
|
||||
atapi_cdb[16],
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
features, pad0,
|
||||
pad1, pad2;
|
||||
|
||||
uint16_t request_length, max_transfer_len;
|
||||
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len, pos;
|
||||
|
||||
int64_t callback;
|
||||
|
||||
int media_status, data_pos,
|
||||
request_pos, total_read,
|
||||
old_len;
|
||||
|
||||
uint8_t previous_command,
|
||||
pad3, pad4, pad5;
|
||||
} scsi_cdrom_t;
|
||||
#endif
|
||||
|
||||
|
||||
extern scsi_cdrom_t *scsi_cdrom[CDROM_NUM];
|
||||
|
||||
#define scsi_cdrom_sense_error dev->sense[0]
|
||||
#define scsi_cdrom_sense_key dev->sense[2]
|
||||
#define scsi_cdrom_asc dev->sense[12]
|
||||
#define scsi_cdrom_ascq dev->sense[13]
|
||||
#define scsi_cdrom_drive cdrom_drives[id].host_drive
|
||||
|
||||
|
||||
extern void scsi_cdrom_reset(void *p);
|
||||
|
||||
|
||||
#endif /*EMU_SCSI_CDROM_H*/
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* The generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.c 1.0.17 2018/06/02
|
||||
* Version: @(#)scsi_device.c 1.0.18 2018/10/10
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -25,325 +25,153 @@
|
||||
#include "../disk/hdd.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
scsi_device_t scsi_devices[SCSI_ID_MAX];
|
||||
|
||||
uint8_t scsi_null_device_sense[18] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0,0,0,0,0 };
|
||||
|
||||
|
||||
static uint8_t
|
||||
scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
||||
scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_command(scsi_disk[id], cdb);
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
cdrom_command(cdrom[id], cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
case SCSI_ZIP:
|
||||
zip_command(zip[id], cdb);
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
if (dev->command && dev->err_stat_to_scsi) {
|
||||
dev->command(dev->p, cdb);
|
||||
return dev->err_stat_to_scsi(dev->p);
|
||||
} else
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
|
||||
|
||||
static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||
static void scsi_device_target_callback(scsi_device_t *dev)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_callback(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
cdrom_phase_callback(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
zip_phase_callback(zip[id]);
|
||||
break;
|
||||
}
|
||||
if (dev->callback)
|
||||
dev->callback(dev->p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||
static int scsi_device_target_err_stat_to_scsi(scsi_device_t *dev)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
case SCSI_ZIP:
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
if (dev->err_stat_to_scsi)
|
||||
return dev->err_stat_to_scsi(dev->p);
|
||||
else
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
|
||||
|
||||
int64_t scsi_device_get_callback(uint8_t scsi_id)
|
||||
int64_t scsi_device_get_callback(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
scsi_device_data_t *sdd = (scsi_device_data_t *) dev->p;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->callback;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->callback;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->callback;
|
||||
break;
|
||||
default:
|
||||
return -1LL;
|
||||
break;
|
||||
}
|
||||
if (sdd)
|
||||
return sdd->callback;
|
||||
else
|
||||
return -1LL;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *scsi_device_sense(uint8_t scsi_id)
|
||||
uint8_t *scsi_device_sense(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
scsi_device_data_t *sdd = (scsi_device_data_t *) dev->p;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->sense;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->sense;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->sense;
|
||||
break;
|
||||
default:
|
||||
return scsi_null_device_sense;
|
||||
break;
|
||||
}
|
||||
if (sdd)
|
||||
return sdd->sense;
|
||||
else
|
||||
return scsi_null_device_sense;
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer, uint8_t alloc_length)
|
||||
void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_request_sense_for_scsi(zip[id], buffer, alloc_length);
|
||||
break;
|
||||
default:
|
||||
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||
break;
|
||||
}
|
||||
if (dev->request_sense)
|
||||
dev->request_sense(dev, buffer, alloc_length);
|
||||
else
|
||||
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_reset(uint8_t scsi_id)
|
||||
void scsi_device_reset(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_reset(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_reset(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_reset(zip[id]);
|
||||
break;
|
||||
}
|
||||
if (dev->reset)
|
||||
dev->reset(dev->p);
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t *type, uint8_t *rmb)
|
||||
void scsi_device_type_data(scsi_device_t *dev, uint8_t *type, uint8_t *rmb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
*type = *rmb = 0x00;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
*type = 0x05;
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
*type = 0x00;
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
default:
|
||||
*type = *rmb = 0xff;
|
||||
break;
|
||||
}
|
||||
*rmb = dev->type >> 8;
|
||||
*type = dev->type & 0xff;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
int scsi_device_read_capacity(scsi_device_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len);
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom_read_capacity(cdrom[id], cdb, buffer, len);
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip_read_capacity(zip[id], cdb, buffer, len);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (dev->read_capacity)
|
||||
return dev->read_capacity(dev->p, cdb, buffer, len);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_present(uint8_t scsi_id)
|
||||
int scsi_device_present(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_NONE:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
if (dev->type == SCSI_NONE)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_valid(uint8_t scsi_id)
|
||||
int scsi_device_valid(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return (id == 0xFF) ? 0 : 1;
|
||||
if (dev->p)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_cdb_length(uint8_t scsi_id)
|
||||
int scsi_device_cdb_length(scsi_device_t *dev)
|
||||
{
|
||||
/* Right now, it's 12 for all devices. */
|
||||
return 12;
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb)
|
||||
void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb)
|
||||
{
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_STATUS;
|
||||
SCSIDevices[scsi_id].Status = SCSI_STATUS_CHECK_CONDITION;
|
||||
return;
|
||||
if (!dev->p) {
|
||||
dev->phase = SCSI_PHASE_STATUS;
|
||||
dev->status = SCSI_STATUS_CHECK_CONDITION;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_COMMAND;
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_command(lun_type, id, cdb);
|
||||
dev->phase = SCSI_PHASE_COMMAND;
|
||||
dev->status = scsi_device_target_command(dev, cdb);
|
||||
|
||||
if (SCSIDevices[scsi_id].Phase == SCSI_PHASE_STATUS) {
|
||||
if (dev->phase == SCSI_PHASE_STATUS) {
|
||||
/* Command completed (either OK or error) - call the phase callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
scsi_device_target_callback(dev);
|
||||
}
|
||||
/* If the phase is DATA IN or DATA OUT, finish this here. */
|
||||
}
|
||||
|
||||
void scsi_device_command_phase1(uint8_t scsi_id)
|
||||
void scsi_device_command_phase1(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
return;
|
||||
}
|
||||
if (!dev->p)
|
||||
return;
|
||||
|
||||
/* Call the second phase. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||
scsi_device_target_callback(dev);
|
||||
dev->status = scsi_device_target_err_stat_to_scsi(dev);
|
||||
/* Command second phase complete - call the callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
scsi_device_target_callback(dev);
|
||||
}
|
||||
|
||||
int32_t *scsi_device_get_buf_len(uint8_t scsi_id)
|
||||
int32_t *scsi_device_get_buf_len(scsi_device_t *dev)
|
||||
{
|
||||
return &SCSIDevices[scsi_id].BufferLength;
|
||||
return &dev->buffer_length;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.h 1.0.10 2018/10/07
|
||||
* Version: @(#)scsi_device.h 1.0.11 2018/10/09
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -250,6 +250,15 @@
|
||||
|
||||
#define BUS_IDLE (1 << 31)
|
||||
|
||||
#define PHASE_IDLE 0x00
|
||||
#define PHASE_COMMAND 0x01
|
||||
#define PHASE_COMPLETE 0x02
|
||||
#define PHASE_DATA_IN 0x03
|
||||
#define PHASE_DATA_IN_DMA 0x04
|
||||
#define PHASE_DATA_OUT 0x05
|
||||
#define PHASE_DATA_OUT_DMA 0x06
|
||||
#define PHASE_ERROR 0x80
|
||||
|
||||
#define SCSI_PHASE_DATA_OUT 0
|
||||
#define SCSI_PHASE_DATA_IN BUS_IO
|
||||
#define SCSI_PHASE_COMMAND BUS_CD
|
||||
@@ -264,28 +273,38 @@
|
||||
#define MODE_SELECT_PHASE_PAGE 4
|
||||
|
||||
|
||||
/* This is probably no longer needed. */
|
||||
#if 0
|
||||
typedef struct
|
||||
{
|
||||
int state;
|
||||
int new_state;
|
||||
int clear_req;
|
||||
uint32_t bus_in, bus_out;
|
||||
int dev_id;
|
||||
uint8_t command[20];
|
||||
|
||||
int command_pos;
|
||||
uint8_t command[20];
|
||||
int data_pos;
|
||||
|
||||
int change_state_delay;
|
||||
int new_req_delay;
|
||||
int state, new_state,
|
||||
clear_req, dev_id,
|
||||
command_pos, data_pos,
|
||||
change_state_delay,
|
||||
new_req_delay;
|
||||
|
||||
uint32_t bus_in, bus_out;
|
||||
} scsi_bus_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t *CmdBuffer;
|
||||
int LunType;
|
||||
int32_t BufferLength;
|
||||
uint8_t Status;
|
||||
uint8_t Phase;
|
||||
uint8_t *cmd_buffer;
|
||||
|
||||
int32_t buffer_length;
|
||||
|
||||
uint8_t status, phase;
|
||||
uint16_t type;
|
||||
|
||||
void *p;
|
||||
|
||||
void (*command)(void *p, uint8_t *cdb);
|
||||
void (*callback)(void *p);
|
||||
int (*err_stat_to_scsi)(void *p);
|
||||
void (*request_sense)(void *p, uint8_t *buffer, uint8_t alloc_length);
|
||||
void (*reset)(void *p);
|
||||
int (*read_capacity)(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
} scsi_device_t;
|
||||
|
||||
#pragma pack(push,1)
|
||||
@@ -294,15 +313,43 @@ typedef struct {
|
||||
} mode_sense_pages_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
enum {
|
||||
SCSI_NONE = 0,
|
||||
SCSI_DISK,
|
||||
SCSI_CDROM,
|
||||
SCSI_ZIP
|
||||
};
|
||||
/* This is so we can access the common elements to all SCSI device structs
|
||||
without knowing the device type. */
|
||||
typedef struct {
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
void *p;
|
||||
|
||||
extern scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
uint8_t *temp_buffer,
|
||||
pad[16], /* This is atapi_cdb in ATAPI-supporting devices,
|
||||
and pad in SCSI-only devices. */
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
features, pad0,
|
||||
pad1, pad2;
|
||||
|
||||
uint16_t request_length, max_transfer_len;
|
||||
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len, pos;
|
||||
|
||||
int64_t callback;
|
||||
} scsi_device_data_t;
|
||||
|
||||
/* These are based on the INQUIRY values. */
|
||||
#define SCSI_NONE 0x0060
|
||||
#define SCSI_FIXED_DISK 0x0000
|
||||
#define SCSI_REMOVABLE_DISK 0x8000
|
||||
#define SCSI_REMOVABLE_CDROM 0x8005
|
||||
|
||||
extern scsi_device_t scsi_devices[SCSI_ID_MAX];
|
||||
|
||||
|
||||
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
|
||||
@@ -312,20 +359,19 @@ extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save
|
||||
extern int mode_select_terminate(int force);
|
||||
extern int mode_select_write(uint8_t val);
|
||||
|
||||
extern uint8_t *scsi_device_sense(uint8_t id);
|
||||
extern void scsi_device_type_data(uint8_t id, uint8_t *type, uint8_t *rmb);
|
||||
extern int64_t scsi_device_get_callback(uint8_t scsi_id);
|
||||
extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer,
|
||||
extern uint8_t *scsi_device_sense(scsi_device_t *dev);
|
||||
extern void scsi_device_type_data(scsi_device_t *dev, uint8_t *type, uint8_t *rmb);
|
||||
extern int64_t scsi_device_get_callback(scsi_device_t *dev);
|
||||
extern void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer,
|
||||
uint8_t alloc_length);
|
||||
extern void scsi_device_reset(uint8_t scsi_id);
|
||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t *cdb,
|
||||
extern void scsi_device_reset(scsi_device_t *dev);
|
||||
extern int scsi_device_read_capacity(scsi_device_t *dev, uint8_t *cdb,
|
||||
uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_device_present(uint8_t id);
|
||||
extern int scsi_device_valid(uint8_t id);
|
||||
extern int scsi_device_cdb_length(uint8_t id);
|
||||
extern void scsi_device_command(uint8_t id, int cdb_len, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(uint8_t scsi_id);
|
||||
extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id);
|
||||
extern int scsi_device_present(scsi_device_t *dev);
|
||||
extern int scsi_device_valid(scsi_device_t *dev);
|
||||
extern int scsi_device_cdb_length(scsi_device_t *dev);
|
||||
extern void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(scsi_device_t *dev);
|
||||
extern int32_t *scsi_device_get_buf_len(scsi_device_t *dev);
|
||||
|
||||
#endif /*SCSI_DEVICE_H*/
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "../plat.h"
|
||||
#include "../ui.h"
|
||||
#include "scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
@@ -54,12 +53,8 @@
|
||||
#define scsi_disk_ascq dev->sense[13]
|
||||
|
||||
|
||||
scsi_disk_t *scsi_disk[HDD_NUM];
|
||||
|
||||
uint8_t scsi_disks[16] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
scsi_disk_t *scsi_disk[HDD_NUM] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
|
||||
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
||||
@@ -145,6 +140,9 @@ static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable =
|
||||
} };
|
||||
|
||||
|
||||
static void scsi_disk_callback(void *p);
|
||||
|
||||
|
||||
#ifdef ENABLE_SCSI_DISK_LOG
|
||||
int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG;
|
||||
#endif
|
||||
@@ -166,9 +164,11 @@ scsi_disk_log(const char *fmt, ...)
|
||||
|
||||
|
||||
/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */
|
||||
int
|
||||
scsi_disk_err_stat_to_scsi(scsi_disk_t *dev)
|
||||
static int
|
||||
scsi_disk_err_stat_to_scsi(void *p)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
if (dev->status & ERR_STAT)
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
else
|
||||
@@ -176,48 +176,6 @@ scsi_disk_err_stat_to_scsi(scsi_disk_t *dev)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
find_hdd_for_scsi_id(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < HDD_NUM; i++) {
|
||||
if (wcslen(hdd[i].fn) == 0)
|
||||
continue;
|
||||
if ((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0))
|
||||
continue;
|
||||
if ((hdd[i].bus == HDD_BUS_SCSI) && (hdd[i].scsi_id == scsi_id))
|
||||
return i;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_loadhd(int scsi_id, int id)
|
||||
{
|
||||
if (! hdd_image_load(id))
|
||||
scsi_disks[scsi_id] = 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
build_scsi_disk_map(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
memset(scsi_disks, 0xff, 16);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
scsi_disks[i] = find_hdd_for_scsi_id(i);
|
||||
if (scsi_disks[i] != 0xff) {
|
||||
if (wcslen(hdd[scsi_disks[i]].fn) > 0)
|
||||
scsi_loadhd(i, scsi_disks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_mode_sense_load(scsi_disk_t *dev)
|
||||
{
|
||||
@@ -256,9 +214,10 @@ scsi_disk_mode_sense_save(scsi_disk_t *dev)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
static int
|
||||
scsi_disk_read_capacity(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
int size = 0;
|
||||
|
||||
size = hdd_image_get_last_sector(dev->id);
|
||||
@@ -296,14 +255,14 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page,
|
||||
|
||||
|
||||
uint32_t
|
||||
scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len)
|
||||
scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
||||
{
|
||||
uint8_t msplen, page_control = (type >> 6) & 3;
|
||||
uint8_t msplen, page_control = (page >> 6) & 3;
|
||||
|
||||
int i = 0, j = 0;
|
||||
int size = 0;
|
||||
|
||||
type &= 0x3f;
|
||||
page &= 0x3f;
|
||||
|
||||
size = hdd_image_get_last_sector(dev->id);
|
||||
|
||||
@@ -319,8 +278,8 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t type,
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
if ((type == GPMODE_ALL_PAGES) || (type == i)) {
|
||||
if (scsi_disk_mode_sense_page_flags & (1LL << dev->current_page_code)) {
|
||||
if ((page == GPMODE_ALL_PAGES) || (page == i)) {
|
||||
if (scsi_disk_mode_sense_page_flags & (1LL << (uint64_t) page)) {
|
||||
buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 0);
|
||||
msplen = scsi_disk_mode_sense_read(dev, page_control, i, 1);
|
||||
buf[pos++] = msplen;
|
||||
@@ -340,8 +299,8 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
{
|
||||
dev->status = BUSY_STAT;
|
||||
dev->phase = 1;
|
||||
if (dev->packet_status == CDROM_PHASE_COMPLETE) {
|
||||
scsi_disk_callback(dev);
|
||||
if (dev->packet_status == PHASE_COMPLETE) {
|
||||
scsi_disk_callback((void *) dev);
|
||||
dev->callback = 0LL;
|
||||
} else
|
||||
dev->callback = -1LL; /* Speed depends on SCSI controller */
|
||||
@@ -351,7 +310,7 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_command_complete(scsi_disk_t *dev)
|
||||
{
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
scsi_disk_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -359,7 +318,7 @@ scsi_disk_command_complete(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_command_read_dma(scsi_disk_t *dev)
|
||||
{
|
||||
dev->packet_status = CDROM_PHASE_DATA_IN_DMA;
|
||||
dev->packet_status = PHASE_DATA_IN_DMA;
|
||||
scsi_disk_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -367,7 +326,7 @@ scsi_disk_command_read_dma(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_command_write_dma(scsi_disk_t *dev)
|
||||
{
|
||||
dev->packet_status = CDROM_PHASE_DATA_OUT_DMA;
|
||||
dev->packet_status = PHASE_DATA_OUT_DMA;
|
||||
scsi_disk_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -407,7 +366,7 @@ scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase)
|
||||
if (dev->drv->bus != HDD_BUS_SCSI)
|
||||
return;
|
||||
|
||||
SCSIDevices[scsi_id].Phase = phase;
|
||||
scsi_devices[scsi_id].phase = phase;
|
||||
}
|
||||
|
||||
|
||||
@@ -533,9 +492,11 @@ scsi_disk_rezero(scsi_disk_t *dev)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_reset(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_reset(void *p)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
scsi_disk_rezero(dev);
|
||||
dev->status = 0;
|
||||
dev->callback = 0;
|
||||
@@ -568,9 +529,11 @@ scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length)
|
||||
static void
|
||||
scsi_disk_request_sense_for_scsi(void *p, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
scsi_disk_request_sense(dev, buffer, alloc_length, 0);
|
||||
}
|
||||
|
||||
@@ -588,9 +551,10 @@ scsi_disk_set_buf_len(scsi_disk_t *dev, int32_t *BufLen, int32_t *src_len)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
static void
|
||||
scsi_disk_command(void *p, uint8_t *cdb)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
uint8_t *hdbufferb;
|
||||
int32_t *BufLen;
|
||||
int32_t len, max_len, alloc_length;
|
||||
@@ -602,8 +566,8 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
|
||||
int block_desc = 0;
|
||||
|
||||
hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer;
|
||||
BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength;
|
||||
hdbufferb = scsi_devices[dev->drv->scsi_id].cmd_buffer;
|
||||
BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
|
||||
|
||||
last_sector = hdd_image_get_last_sector(dev->id);
|
||||
|
||||
@@ -666,7 +630,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
|
||||
if (!len) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -715,7 +679,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!dev->sector_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
scsi_disk_log("SCSI HD %i: All done - callback set\n", dev);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -779,7 +743,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!dev->sector_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -817,7 +781,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!dev->sector_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -847,8 +811,6 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
else
|
||||
len = (cdb[8] | (cdb[7] << 8));
|
||||
|
||||
dev->current_page_code = cdb[2] & 0x3F;
|
||||
|
||||
alloc_length = len;
|
||||
|
||||
dev->temp_buffer = (uint8_t *) malloc(65536);
|
||||
@@ -909,7 +871,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!max_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
/* scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); */
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -1055,8 +1017,8 @@ atapi_out:
|
||||
static void
|
||||
scsi_disk_phase_data_in(scsi_disk_t *dev)
|
||||
{
|
||||
uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer;
|
||||
int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength;
|
||||
uint8_t *hdbufferb = scsi_devices[dev->drv->scsi_id].cmd_buffer;
|
||||
int32_t *BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
|
||||
|
||||
if (!*BufLen) {
|
||||
scsi_disk_log("scsi_disk_phase_data_in(): Buffer length is 0\n");
|
||||
@@ -1108,9 +1070,9 @@ scsi_disk_phase_data_in(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_phase_data_out(scsi_disk_t *dev)
|
||||
{
|
||||
uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer;
|
||||
uint8_t *hdbufferb = scsi_devices[dev->drv->scsi_id].cmd_buffer;
|
||||
int i;
|
||||
int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength;
|
||||
int32_t *BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
|
||||
uint32_t last_sector = hdd_image_get_last_sector(dev->id);
|
||||
uint32_t c, h, s, last_to_write = 0;
|
||||
uint16_t block_desc_len, pos;
|
||||
@@ -1232,36 +1194,38 @@ scsi_disk_phase_data_out(scsi_disk_t *dev)
|
||||
|
||||
|
||||
/* If the result is 1, issue an IRQ, otherwise not. */
|
||||
void
|
||||
scsi_disk_callback(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_callback(void *p)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
switch(dev->packet_status) {
|
||||
case CDROM_PHASE_IDLE:
|
||||
case PHASE_IDLE:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_IDLE\n", dev->id);
|
||||
dev->phase = 1;
|
||||
dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT);
|
||||
return;
|
||||
case CDROM_PHASE_COMPLETE:
|
||||
case PHASE_COMPLETE:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_COMPLETE\n", dev->id);
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
dev->packet_status = 0xFF;
|
||||
return;
|
||||
case CDROM_PHASE_DATA_OUT_DMA:
|
||||
case PHASE_DATA_OUT_DMA:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", dev->id);
|
||||
scsi_disk_phase_data_out(dev);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
return;
|
||||
case CDROM_PHASE_DATA_IN_DMA:
|
||||
case PHASE_DATA_IN_DMA:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", dev->id);
|
||||
scsi_disk_phase_data_in(dev);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
return;
|
||||
case CDROM_PHASE_ERROR:
|
||||
case PHASE_ERROR:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_ERROR\n", dev->id);
|
||||
dev->status = READY_STAT | ERR_STAT;
|
||||
dev->phase = 3;
|
||||
@@ -1283,20 +1247,47 @@ void
|
||||
scsi_disk_hard_reset(void)
|
||||
{
|
||||
int c;
|
||||
scsi_device_t *sd;
|
||||
|
||||
for (c = 0; c < HDD_NUM; c++) {
|
||||
if (hdd[c].bus == HDD_BUS_SCSI) {
|
||||
scsi_disk_log("SCSI disk hard_reset drive=%d\n", c);
|
||||
|
||||
/* Make sure to ignore any SCSI disk that has an out of range ID. */
|
||||
if (hdd[c].scsi_id > SCSI_ID_MAX)
|
||||
continue;
|
||||
|
||||
/* Make sure to ignore any SCSI disk whose image file name is empty. */
|
||||
if (wcslen(hdd[c].fn) == 0)
|
||||
continue;
|
||||
|
||||
/* Make sure to ignore any SCSI disk whose image fails to load. */
|
||||
if (! hdd_image_load(c))
|
||||
continue;
|
||||
|
||||
if (!scsi_disk[c]) {
|
||||
scsi_disk[c] = (scsi_disk_t *) malloc(sizeof(scsi_disk_t));
|
||||
memset(scsi_disk[c], 0, sizeof(scsi_disk_t));
|
||||
}
|
||||
|
||||
/* SCSI disk, attach to the SCSI bus. */
|
||||
sd = &scsi_devices[hdd[c].scsi_id];
|
||||
|
||||
sd->p = scsi_disk[c];
|
||||
sd->command = scsi_disk_command;
|
||||
sd->callback = scsi_disk_callback;
|
||||
sd->err_stat_to_scsi = scsi_disk_err_stat_to_scsi;
|
||||
sd->request_sense = scsi_disk_request_sense_for_scsi;
|
||||
sd->reset = scsi_disk_reset;
|
||||
sd->read_capacity = scsi_disk_read_capacity;
|
||||
sd->type = SCSI_FIXED_DISK;
|
||||
|
||||
scsi_disk[c]->id = c;
|
||||
scsi_disk[c]->drv = &hdd[c];
|
||||
|
||||
scsi_disk_mode_sense_load(scsi_disk[c]);
|
||||
|
||||
scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.h 1.0.5 2018/06/02
|
||||
* Version: @(#)scsi_disk.h 1.0.6 2018/10/10
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
@@ -18,43 +18,33 @@ typedef struct {
|
||||
|
||||
hard_disk_t *drv;
|
||||
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
uint8_t *temp_buffer,
|
||||
pad[16], /* This is atapi_cdb in ATAPI-supporting devices,
|
||||
and pad in SCSI-only devices. */
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint16_t request_length;
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
pad0, pad1,
|
||||
pad2, pad3;
|
||||
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
uint16_t request_length, pad4;
|
||||
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
packet_len, pos;
|
||||
|
||||
uint64_t current_page_code;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
int64_t callback;
|
||||
} scsi_disk_t;
|
||||
|
||||
|
||||
extern scsi_disk_t *scsi_disk[HDD_NUM];
|
||||
extern uint8_t scsi_disks[16];
|
||||
|
||||
|
||||
extern void scsi_loadhd(int scsi_id, int id);
|
||||
extern void scsi_disk_global_init(void);
|
||||
extern void scsi_disk_hard_reset(void);
|
||||
extern void scsi_disk_close(void);
|
||||
|
||||
extern int scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_disk_err_stat_to_scsi(scsi_disk_t *dev);
|
||||
extern int scsi_disk_phase_to_scsi(scsi_disk_t *dev);
|
||||
extern int find_hdd_for_scsi_id(uint8_t scsi_id);
|
||||
extern void build_scsi_disk_map(void);
|
||||
extern void scsi_disk_reset(scsi_disk_t *dev);
|
||||
extern void scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb);
|
||||
extern void scsi_disk_callback(scsi_disk_t *dev);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the NCR 5380 series of SCSI Host Adapters
|
||||
* made by NCR. These controllers were designed for the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.20 2018/10/08
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.22 2018/10/09
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
@@ -280,19 +280,19 @@ ncr_wait_process(ncr5380_t *ncr_dev)
|
||||
if (ncr->wait_data) {
|
||||
ncr->wait_data--;
|
||||
if (!ncr->wait_data) {
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
SET_BUS_STATE(ncr, ncr->new_phase);
|
||||
|
||||
if (ncr->new_phase == SCSI_PHASE_DATA_IN) {
|
||||
ncr_log("Data In bus phase\n");
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->state = STATE_DATAIN;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP;
|
||||
} else if (ncr->new_phase == SCSI_PHASE_STATUS) {
|
||||
ncr_log("Status bus phase\n");
|
||||
ncr->cur_bus |= BUS_REQ;
|
||||
ncr->state = STATE_STATUS;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->Status) | BUS_DBP;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP;
|
||||
} else if (ncr->new_phase == SCSI_PHASE_MESSAGE_IN) {
|
||||
ncr_log("Message In bus phase\n");
|
||||
ncr->state = STATE_MESSAGEIN;
|
||||
@@ -799,7 +799,7 @@ scsiat_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
ncr_t *ncr = &ncr_dev->ncr;
|
||||
scsi_device_t *dev = &SCSIDevices[ncr->target_id];
|
||||
scsi_device_t *dev = &scsi_devices[ncr->target_id];
|
||||
|
||||
ncr_log("SCSI AT write=0x%03x, val=%02x\n", port, val);
|
||||
switch (port & 0x0f) {
|
||||
@@ -852,7 +852,7 @@ scsiat_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (ncr->unk_08 & 0x01)
|
||||
{
|
||||
ncr_dev->block_count_loaded = 1;
|
||||
ncr_dev->block_count = dev->BufferLength / 128;
|
||||
ncr_dev->block_count = dev->buffer_length / 128;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -875,8 +875,8 @@ ncr_callback(void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
ncr_t *ncr = &ncr_dev->ncr;
|
||||
scsi_device_t *dev = &SCSIDevices[ncr->target_id];
|
||||
int c = 0;
|
||||
scsi_device_t *dev = &scsi_devices[ncr->target_id];
|
||||
int req_len, c = 0;
|
||||
int64_t p;
|
||||
uint8_t temp, data;
|
||||
|
||||
@@ -887,7 +887,7 @@ ncr_callback(void *priv)
|
||||
if (((ncr->state == STATE_DATAIN) || (ncr->state == STATE_DATAOUT)) && (ncr->dma_mode != DMA_IDLE))
|
||||
ncr_dev->timer_period = (int64_t) ncr_dev->period;
|
||||
else
|
||||
ncr_dev->timer_period += 10LL * TIMER_USEC;
|
||||
ncr_dev->timer_period += 40LL * TIMER_USEC;
|
||||
|
||||
if (ncr->dma_mode == DMA_IDLE) {
|
||||
ncr->bus_host = get_bus_host(ncr);
|
||||
@@ -909,7 +909,7 @@ ncr_callback(void *priv)
|
||||
ncr_log("Select - target ID = %i\n", ncr->target_id);
|
||||
|
||||
/*Once the device has been found and selected, mark it as busy*/
|
||||
if ((ncr->target_id != -1) && scsi_device_present(ncr->target_id)) {
|
||||
if ((ncr->target_id != -1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
|
||||
ncr->cur_bus |= BUS_BSY;
|
||||
ncr_log("Device found at ID %i\n", ncr->target_id);
|
||||
ncr_log("Current Bus BSY=%02x\n", ncr->cur_bus);
|
||||
@@ -943,35 +943,36 @@ ncr_callback(void *priv)
|
||||
/*Reset data position to default*/
|
||||
ncr->data_pos = 0;
|
||||
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
|
||||
ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->Status);
|
||||
ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
dev->buffer_length = -1;
|
||||
|
||||
/*Now, execute the given SCSI command*/
|
||||
scsi_device_command_phase0(ncr->target_id, ncr->command);
|
||||
scsi_device_command_phase0(dev, ncr->command);
|
||||
|
||||
ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->BufferLength, dev->Phase);
|
||||
ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase);
|
||||
|
||||
if (dev->Status != SCSI_STATUS_OK) {
|
||||
if (dev->status != SCSI_STATUS_OK) {
|
||||
ncr->new_phase = SCSI_PHASE_STATUS;
|
||||
ncr->wait_data = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
/*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/
|
||||
if (dev->BufferLength && (dev->Phase == SCSI_PHASE_DATA_IN || dev->Phase == SCSI_PHASE_DATA_OUT)) {
|
||||
dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength);
|
||||
if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) {
|
||||
dev->cmd_buffer = (uint8_t *) malloc(dev->buffer_length);
|
||||
|
||||
p = scsi_device_get_callback(ncr->target_id);
|
||||
p = scsi_device_get_callback(dev);
|
||||
req_len = MIN(64, dev->buffer_length);
|
||||
if (p <= 0LL)
|
||||
ncr_dev->period = 0.2 * ((double) TIMER_USEC) * ((double) MIN(64, dev->BufferLength));
|
||||
ncr_dev->period = 0.2 * ((double) TIMER_USEC) * ((double) req_len);
|
||||
else
|
||||
ncr_dev->period = (p / ((double) dev->BufferLength)) * ((double) MIN(64, dev->BufferLength));
|
||||
ncr_dev->period = (p / ((double) dev->buffer_length)) * ((double) req_len);
|
||||
}
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_DATA_OUT) {
|
||||
if (dev->phase == SCSI_PHASE_DATA_OUT) {
|
||||
/* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */
|
||||
ncr_log("Next state is data out\n");
|
||||
ncr->new_phase = SCSI_PHASE_DATA_OUT;
|
||||
@@ -979,23 +980,23 @@ ncr_callback(void *priv)
|
||||
ncr->clear_req = 4;
|
||||
} else {
|
||||
/* Other command - execute immediately. */
|
||||
ncr->new_phase = dev->Phase;
|
||||
ncr->new_phase = dev->phase;
|
||||
|
||||
if (ncr->new_phase == SCSI_PHASE_DATA_IN)
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
ncr->wait_data = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ncr->state == STATE_DATAIN) {
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
ncr_log("Data In ACK=%02x\n", ncr->bus_host & BUS_ACK);
|
||||
if (ncr->bus_host & BUS_ACK) {
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1003,7 +1004,7 @@ ncr_callback(void *priv)
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
ncr->clear_req = 3;
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1011,18 +1012,18 @@ ncr_callback(void *priv)
|
||||
}
|
||||
}
|
||||
} else if (ncr->state == STATE_DATAOUT) {
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
|
||||
ncr_log("Data Out ACK=%02x\n", ncr->bus_host & BUS_ACK);
|
||||
if (ncr->bus_host & BUS_ACK) {
|
||||
dev->CmdBuffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
dev->cmd_buffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1073,10 +1074,10 @@ ncr_callback(void *priv)
|
||||
temp = BUS_GETDATA(ncr->bus_host);
|
||||
ncr->bus_host = get_bus_host(ncr);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1084,7 +1085,7 @@ ncr_callback(void *priv)
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
ncr->clear_req = 3;
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1139,14 +1140,14 @@ ncr_callback(void *priv)
|
||||
ncr->bus_host = get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||
ncr->bus_host |= BUS_SETDATA(data);
|
||||
|
||||
dev->CmdBuffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
dev->cmd_buffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1196,10 +1197,10 @@ ncr_callback(void *priv)
|
||||
temp = BUS_GETDATA(ncr->bus_host);
|
||||
ncr->bus_host = get_bus_host(ncr);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1207,7 +1208,7 @@ ncr_callback(void *priv)
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
ncr->clear_req = 3;
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1248,14 +1249,14 @@ ncr_callback(void *priv)
|
||||
ncr->bus_host = get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||
ncr->bus_host |= BUS_SETDATA(data);
|
||||
|
||||
dev->CmdBuffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
dev->cmd_buffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* NCR and later Symbios and LSI. This controller was designed
|
||||
* for the PCI bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.14 2018/05/28
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.15 2018/10/09
|
||||
*
|
||||
* Authors: Paul Brook (QEMU)
|
||||
* Artyom Tarasenko (QEMU)
|
||||
@@ -391,8 +391,10 @@ ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
dev->gpreg0 = 0;
|
||||
dev->sstop = 1;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
/* This is *NOT* a wide SCSI controller, so do not touch
|
||||
SCSI devices with ID's >= 8. */
|
||||
for (i = 0; i < 8; i++)
|
||||
scsi_device_reset(&scsi_devices[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -595,11 +597,9 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
uint32_t addr, tdbc;
|
||||
int count;
|
||||
|
||||
scsi_device_t *sd;
|
||||
scsi_device_t *sd = &scsi_devices[id];
|
||||
|
||||
sd = &SCSIDevices[id];
|
||||
|
||||
if ((!scsi_device_present(id))) {
|
||||
if ((!scsi_device_present(sd))) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command);
|
||||
return;
|
||||
}
|
||||
@@ -610,7 +610,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure count is never bigger than BufferLength. */
|
||||
/* Make sure count is never bigger than buffer_length. */
|
||||
count = tdbc = dev->dbc;
|
||||
if (count > dev->temp_buf_len)
|
||||
count = dev->temp_buf_len;
|
||||
@@ -622,13 +622,13 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
dev->dbc -= count;
|
||||
|
||||
if (out)
|
||||
ncr53c810_read(dev, addr, sd->CmdBuffer+dev->buffer_pos, count);
|
||||
ncr53c810_read(dev, addr, sd->cmd_buffer + dev->buffer_pos, count);
|
||||
else {
|
||||
if (!dev->buffer_pos) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command);
|
||||
scsi_device_command_phase1(dev->current->tag);
|
||||
scsi_device_command_phase1(&scsi_devices[dev->current->tag]);
|
||||
}
|
||||
ncr53c810_write(dev, addr, sd->CmdBuffer+dev->buffer_pos, count);
|
||||
ncr53c810_write(dev, addr, sd->cmd_buffer + dev->buffer_pos, count);
|
||||
}
|
||||
|
||||
dev->temp_buf_len -= count;
|
||||
@@ -637,13 +637,13 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
if (dev->temp_buf_len <= 0) {
|
||||
if (out) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command);
|
||||
scsi_device_command_phase1(id);
|
||||
scsi_device_command_phase1(&scsi_devices[id]);
|
||||
}
|
||||
if (sd->CmdBuffer != NULL) {
|
||||
free(sd->CmdBuffer);
|
||||
sd->CmdBuffer = NULL;
|
||||
if (sd->cmd_buffer != NULL) {
|
||||
free(sd->cmd_buffer);
|
||||
sd->cmd_buffer = NULL;
|
||||
}
|
||||
ncr53c810_command_complete(dev, sd->Status);
|
||||
ncr53c810_command_complete(dev, sd->status);
|
||||
} else {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Resume SCRIPTS\n", id, dev->current_lun, dev->last_command);
|
||||
dev->sstop = 0;
|
||||
@@ -683,8 +683,8 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->sfbr = buf[0];
|
||||
dev->command_complete = 0;
|
||||
|
||||
sd = &SCSIDevices[id];
|
||||
if (!scsi_device_present(id)) {
|
||||
sd = &scsi_devices[id];
|
||||
if (!scsi_device_present(sd)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
return 0;
|
||||
@@ -693,46 +693,46 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->current = (ncr53c810_request*)malloc(sizeof(ncr53c810_request));
|
||||
dev->current->tag = id;
|
||||
|
||||
sd->BufferLength = -1;
|
||||
sd->buffer_length = -1;
|
||||
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DBC=%i\n", id, dev->current_lun, buf[0], dev->dbc);
|
||||
dev->last_command = buf[0];
|
||||
|
||||
scsi_device_command_phase0(dev->current->tag, buf);
|
||||
scsi_device_command_phase0(&scsi_devices[dev->current->tag], buf);
|
||||
dev->hba_private = (void *)dev->current;
|
||||
|
||||
dev->waiting = 0;
|
||||
dev->buffer_pos = 0;
|
||||
|
||||
dev->temp_buf_len = sd->BufferLength;
|
||||
dev->temp_buf_len = sd->buffer_length;
|
||||
|
||||
if (sd->BufferLength > 0) {
|
||||
sd->CmdBuffer = (uint8_t *)malloc(sd->BufferLength);
|
||||
dev->current->dma_len = sd->BufferLength;
|
||||
if (sd->buffer_length > 0) {
|
||||
sd->cmd_buffer = (uint8_t *)malloc(sd->buffer_length);
|
||||
dev->current->dma_len = sd->buffer_length;
|
||||
}
|
||||
|
||||
if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) {
|
||||
if ((sd->phase == SCSI_PHASE_DATA_IN) && (sd->buffer_length > 0)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_set_phase(dev, PHASE_DI);
|
||||
p = scsi_device_get_callback(dev->current->tag);
|
||||
p = scsi_device_get_callback(&scsi_devices[dev->current->tag]);
|
||||
if (p <= 0LL) {
|
||||
period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
period = ((double) sd->buffer_length) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
dev->timer_period += (int64_t) period;
|
||||
} else
|
||||
dev->timer_period += p;
|
||||
return 1;
|
||||
} else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) {
|
||||
} else if ((sd->phase == SCSI_PHASE_DATA_OUT) && (sd->buffer_length > 0)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]);
|
||||
ncr53c810_set_phase(dev, PHASE_DO);
|
||||
p = scsi_device_get_callback(dev->current->tag);
|
||||
p = scsi_device_get_callback(&scsi_devices[dev->current->tag]);
|
||||
if (p <= 0LL) {
|
||||
period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
period = ((double) sd->buffer_length) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
dev->timer_period += (int64_t) period;
|
||||
} else
|
||||
dev->timer_period += p;
|
||||
return 1;
|
||||
} else {
|
||||
ncr53c810_command_complete(dev, sd->Status);
|
||||
ncr53c810_command_complete(dev, sd->status);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -832,7 +832,7 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
uint32_t current_tag;
|
||||
scsi_device_t *sd;
|
||||
|
||||
sd = &SCSIDevices[id];
|
||||
sd = &scsi_devices[id];
|
||||
|
||||
current_tag = id;
|
||||
|
||||
@@ -884,9 +884,9 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
case 0x0d:
|
||||
/* The ABORT TAG message clears the current I/O process only. */
|
||||
ncr53c810_log("MSG: ABORT TAG tag=0x%x\n", current_tag);
|
||||
if (sd->CmdBuffer) {
|
||||
free(sd->CmdBuffer);
|
||||
sd->CmdBuffer = NULL;
|
||||
if (sd->cmd_buffer) {
|
||||
free(sd->cmd_buffer);
|
||||
sd->cmd_buffer = NULL;
|
||||
}
|
||||
ncr53c810_disconnect(dev);
|
||||
break;
|
||||
@@ -907,9 +907,9 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
ncr53c810_log("MSG: BUS DEVICE RESET tag=0x%x\n", current_tag);
|
||||
|
||||
/* clear the current I/O process */
|
||||
if (sd->CmdBuffer) {
|
||||
free(sd->CmdBuffer);
|
||||
sd->CmdBuffer = NULL;
|
||||
if (sd->cmd_buffer) {
|
||||
free(sd->cmd_buffer);
|
||||
sd->cmd_buffer = NULL;
|
||||
}
|
||||
ncr53c810_disconnect(dev);
|
||||
break;
|
||||
@@ -1078,7 +1078,7 @@ again:
|
||||
}
|
||||
dev->sstat0 |= NCR_SSTAT0_WOA;
|
||||
dev->scntl1 &= ~NCR_SCNTL1_IARB;
|
||||
if (!scsi_device_present(id)) {
|
||||
if (!scsi_device_present(&scsi_devices[id])) {
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* series of SCSI Host Adapters made by Mylex.
|
||||
* These controllers were designed for various buses.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.c 1.0.22 2018/10/02
|
||||
* Version: @(#)scsi_x54x.c 1.0.23 2018/10/09
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -155,9 +155,8 @@ clear_irq(x54x_t *dev)
|
||||
static void
|
||||
target_check(uint8_t id)
|
||||
{
|
||||
if (! scsi_device_valid(id)) {
|
||||
if (! scsi_device_valid(&scsi_devices[id]))
|
||||
fatal("BIOS INT13 device on ID %02i has disappeared\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,9 +236,10 @@ x54x_bios_command_08(uint8_t id, uint8_t *buffer)
|
||||
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
|
||||
uint32_t len = 0;
|
||||
int i, ret, sc;
|
||||
scsi_device_t *sd = &scsi_devices[id];
|
||||
|
||||
ret = scsi_device_read_capacity(id, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id));
|
||||
ret = scsi_device_read_capacity(sd, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(sd));
|
||||
if (ret == 0) return(sc);
|
||||
|
||||
memset(buffer, 0x00, 6);
|
||||
@@ -261,15 +261,16 @@ x54x_bios_command_15(uint8_t id, uint8_t *buffer)
|
||||
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
|
||||
uint32_t len = 0;
|
||||
int i, ret, sc;
|
||||
scsi_device_t *sd = &scsi_devices[id];
|
||||
|
||||
ret = scsi_device_read_capacity(id, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id));
|
||||
ret = scsi_device_read_capacity(sd, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(sd));
|
||||
|
||||
memset(buffer, 0x00, 6);
|
||||
for (i=0; i<4; i++)
|
||||
buffer[i] = (ret == 0) ? 0 : rcbuf[i];
|
||||
|
||||
scsi_device_type_data(id, &(buffer[4]), &(buffer[5]));
|
||||
scsi_device_type_data(sd, &(buffer[4]), &(buffer[5]));
|
||||
|
||||
x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n",
|
||||
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
|
||||
@@ -308,15 +309,15 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
}
|
||||
|
||||
/* Get pointer to selected device. */
|
||||
dev = &SCSIDevices[cmd->id];
|
||||
dev->BufferLength = 0;
|
||||
dev = &scsi_devices[cmd->id];
|
||||
dev->buffer_length = 0;
|
||||
|
||||
if (! scsi_device_present(cmd->id)) {
|
||||
if (! scsi_device_present(dev)) {
|
||||
x54x_log("BIOS Target ID %i has no device attached\n", cmd->id);
|
||||
return(0x80);
|
||||
}
|
||||
|
||||
if ((dev->LunType == SCSI_CDROM) && !x54x->cdrom_boot) {
|
||||
if ((dev->type == SCSI_REMOVABLE_CDROM) && !x54x->cdrom_boot) {
|
||||
x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id);
|
||||
return(0x80);
|
||||
}
|
||||
@@ -326,9 +327,9 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n",
|
||||
sector_len, dma_address);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
switch(cmd->command) {
|
||||
@@ -343,20 +344,20 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
* length for SCSI sense, and no command-specific
|
||||
* indication is given.
|
||||
*/
|
||||
dev->BufferLength = 14;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(14);
|
||||
memset(dev->CmdBuffer, 0x00, 14);
|
||||
dev->buffer_length = 14;
|
||||
dev->cmd_buffer = (uint8_t *)malloc(14);
|
||||
memset(dev->cmd_buffer, 0x00, 14);
|
||||
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading 14 bytes at %08X\n",
|
||||
dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
scsi_device_sense(cmd->id), 14);
|
||||
scsi_device_sense(dev), 14);
|
||||
}
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(0);
|
||||
@@ -364,7 +365,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
case 0x02: /* Read Desired Sectors to Memory */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
dev->buffer_length = -1;
|
||||
|
||||
cdb[0] = GPCMD_READ_10;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
@@ -378,33 +379,33 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount);
|
||||
#endif
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_STATUS)
|
||||
if (dev->phase == SCSI_PHASE_STATUS)
|
||||
goto skip_read_phase1;
|
||||
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
|
||||
scsi_device_command_phase1(cmd->id);
|
||||
scsi_device_command_phase1(dev);
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||
dev->BufferLength, dma_address);
|
||||
dev->buffer_length, dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
dev->CmdBuffer, dev->BufferLength);
|
||||
dev->cmd_buffer, dev->buffer_length);
|
||||
}
|
||||
|
||||
skip_read_phase1:
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x03: /* Write Desired Sectors from Memory */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
dev->buffer_length = -1;
|
||||
|
||||
cdb[0] = GPCMD_WRITE_10;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
@@ -418,29 +419,29 @@ skip_read_phase1:
|
||||
x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount);
|
||||
#endif
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_STATUS)
|
||||
if (dev->phase == SCSI_PHASE_STATUS)
|
||||
goto skip_write_phase1;
|
||||
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||
dev->BufferLength, dma_address);
|
||||
dev->buffer_length, dma_address);
|
||||
DMAPageRead(dma_address,
|
||||
dev->CmdBuffer, dev->BufferLength);
|
||||
dev->cmd_buffer, dev->buffer_length);
|
||||
}
|
||||
|
||||
scsi_device_command_phase1(cmd->id);
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
skip_write_phase1:
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x04: /* Verify Desired Sectors */
|
||||
target_check(cmd->id);
|
||||
@@ -454,9 +455,9 @@ skip_write_phase1:
|
||||
cdb[7] = 0;
|
||||
cdb[8] = sector_len;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x05: /* Format Track, invalid since SCSI has no tracks */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -472,26 +473,26 @@ skip_write_phase1:
|
||||
cdb[0] = GPCMD_FORMAT_UNIT;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x08: /* Read Drive Parameters */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = 6;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
memset(dev->CmdBuffer, 0x00, dev->BufferLength);
|
||||
dev->buffer_length = 6;
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
memset(dev->cmd_buffer, 0x00, dev->buffer_length);
|
||||
|
||||
ret = x54x_bios_command_08(cmd->id, dev->CmdBuffer);
|
||||
ret = x54x_bios_command_08(cmd->id, dev->cmd_buffer);
|
||||
|
||||
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
dev->CmdBuffer, 4 /* dev->BufferLength */);
|
||||
dev->cmd_buffer, 4 /* dev->buffer_length */);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
@@ -510,9 +511,9 @@ skip_write_phase1:
|
||||
cdb[4] = (lba >> 8) & 0xff;
|
||||
cdb[5] = lba & 0xff;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return((dev->Status == SCSI_STATUS_OK) ? 1 : 0);
|
||||
return((dev->status == SCSI_STATUS_OK) ? 1 : 0);
|
||||
|
||||
case 0x0d: /* Alternate Disk Reset, in practice it's a nop */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -524,9 +525,9 @@ skip_write_phase1:
|
||||
cdb[0] = GPCMD_TEST_UNIT_READY;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x11: /* Recalibrate */
|
||||
target_check(cmd->id);
|
||||
@@ -534,9 +535,9 @@ skip_write_phase1:
|
||||
cdb[0] = GPCMD_REZERO_UNIT;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x14: /* Controller Diagnostic */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -545,19 +546,19 @@ skip_write_phase1:
|
||||
case 0x15: /* Read DASD Type */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = 6;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
memset(dev->CmdBuffer, 0x00, dev->BufferLength);
|
||||
dev->buffer_length = 6;
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
memset(dev->cmd_buffer, 0x00, dev->buffer_length);
|
||||
|
||||
ret = x54x_bios_command_15(cmd->id, dev->CmdBuffer);
|
||||
ret = x54x_bios_command_15(cmd->id, dev->cmd_buffer);
|
||||
|
||||
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
dev->CmdBuffer, 4 /* dev->BufferLength */);
|
||||
dev->cmd_buffer, 4 /* dev->buffer_length */);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
@@ -761,7 +762,7 @@ x54x_set_residue(Req_t *req, int32_t TransferLength)
|
||||
{
|
||||
uint32_t Residue = 0;
|
||||
addr24 Residue24;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID].BufferLength;
|
||||
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
|
||||
|
||||
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
||||
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
||||
@@ -792,7 +793,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
uint32_t DataPointer, DataLength;
|
||||
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
|
||||
uint32_t Address, i;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID].BufferLength;
|
||||
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
|
||||
uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
int sg_pos = 0;
|
||||
@@ -824,11 +825,11 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if (read_from_host && DataToTransfer) {
|
||||
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
DMAPageRead(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
DMAPageRead(Address, &(scsi_devices[req->TargetID].cmd_buffer[sg_pos]), DataToTransfer);
|
||||
}
|
||||
else if (write_to_host && DataToTransfer) {
|
||||
x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
DMAPageWrite(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
DMAPageWrite(Address, &(scsi_devices[req->TargetID].cmd_buffer[sg_pos]), DataToTransfer);
|
||||
}
|
||||
else
|
||||
x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
@@ -848,9 +849,9 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
|
||||
if (read_from_host)
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
DMAPageRead(Address, scsi_devices[req->TargetID].cmd_buffer, MIN(BufLen, (int) DataLength));
|
||||
else if (write_to_host)
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
DMAPageWrite(Address, scsi_devices[req->TargetID].cmd_buffer, MIN(BufLen, (int) DataLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -860,23 +861,23 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
void
|
||||
x54x_buf_alloc(uint8_t id, int length)
|
||||
{
|
||||
if (SCSIDevices[id].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
if (scsi_devices[id].cmd_buffer != NULL) {
|
||||
free(scsi_devices[id].cmd_buffer);
|
||||
scsi_devices[id].cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
x54x_log("Allocating data buffer (%i bytes)\n", length);
|
||||
SCSIDevices[id].CmdBuffer = (uint8_t *) malloc(length);
|
||||
memset(SCSIDevices[id].CmdBuffer, 0, length);
|
||||
scsi_devices[id].cmd_buffer = (uint8_t *) malloc(length);
|
||||
memset(scsi_devices[id].cmd_buffer, 0, length);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
x54x_buf_free(uint8_t id)
|
||||
{
|
||||
if (SCSIDevices[id].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
if (scsi_devices[id].cmd_buffer != NULL) {
|
||||
free(scsi_devices[id].cmd_buffer);
|
||||
scsi_devices[id].cmd_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,7 +921,7 @@ SenseBufferFree(Req_t *req, int Copy)
|
||||
uint8_t temp_sense[256];
|
||||
|
||||
if (SenseLength && Copy) {
|
||||
scsi_device_request_sense(req->TargetID, temp_sense, SenseLength);
|
||||
scsi_device_request_sense(&scsi_devices[req->TargetID], temp_sense, SenseLength);
|
||||
|
||||
/*
|
||||
* The sense address, in 32-bit mode, is located in the
|
||||
@@ -945,24 +946,22 @@ static void
|
||||
x54x_scsi_cmd(x54x_t *dev)
|
||||
{
|
||||
Req_t *req = &dev->Req;
|
||||
uint8_t id, lun;
|
||||
uint8_t id, lun, phase, bit24 = !!req->Is24bit;
|
||||
uint8_t temp_cdb[12];
|
||||
uint32_t i;
|
||||
int target_cdb_len = 12;
|
||||
int target_data_len;
|
||||
uint8_t bit24 = !!req->Is24bit;
|
||||
uint32_t i, SenseBufferAddress;
|
||||
int target_data_len, target_cdb_len = 12;
|
||||
int32_t *BufLen;
|
||||
uint8_t phase;
|
||||
uint32_t SenseBufferAddress;
|
||||
int64_t p;
|
||||
scsi_device_t *sd;
|
||||
|
||||
id = req->TargetID;
|
||||
sd = &scsi_devices[id];
|
||||
lun = req->LUN;
|
||||
|
||||
target_cdb_len = 12;
|
||||
target_data_len = x54x_get_length(req, bit24);
|
||||
|
||||
if (!scsi_device_valid(id))
|
||||
if (!scsi_device_valid(sd))
|
||||
fatal("SCSI target on %02i has disappeared\n", id);
|
||||
|
||||
x54x_log("target_data_len = %i\n", target_data_len);
|
||||
@@ -985,14 +984,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
|
||||
dev->Residue = 0;
|
||||
|
||||
BufLen = scsi_device_get_buf_len(id);
|
||||
BufLen = scsi_device_get_buf_len(sd);
|
||||
*BufLen = target_data_len;
|
||||
|
||||
x54x_log("Command buffer: %08X\n", SCSIDevices[id].CmdBuffer);
|
||||
x54x_log("Command buffer: %08X\n", scsi_devices[id].cmd_buffer);
|
||||
|
||||
scsi_device_command_phase0(id, temp_cdb);
|
||||
scsi_device_command_phase0(sd, temp_cdb);
|
||||
|
||||
phase = SCSIDevices[id].Phase;
|
||||
phase = sd->phase;
|
||||
|
||||
x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03));
|
||||
|
||||
@@ -1001,14 +1000,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
/* Request sense in non-data mode - sense goes to sense buffer. */
|
||||
*BufLen = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
|
||||
x54x_buf_alloc(id, *BufLen);
|
||||
scsi_device_command_phase1(id);
|
||||
if ((SCSIDevices[id].Status != SCSI_STATUS_OK) && (*BufLen > 0)) {
|
||||
scsi_device_command_phase1(sd);
|
||||
if ((sd->status != SCSI_STATUS_OK) && (*BufLen > 0)) {
|
||||
SenseBufferAddress = SenseBufferPointer(req);
|
||||
DMAPageWrite(SenseBufferAddress, SCSIDevices[id].CmdBuffer, *BufLen);
|
||||
DMAPageWrite(SenseBufferAddress, scsi_devices[id].cmd_buffer, *BufLen);
|
||||
x54x_add_to_period(*BufLen);
|
||||
}
|
||||
} else {
|
||||
p = scsi_device_get_callback(id);
|
||||
p = scsi_device_get_callback(sd);
|
||||
if (p <= 0LL)
|
||||
x54x_add_to_period(*BufLen);
|
||||
else
|
||||
@@ -1016,14 +1015,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
x54x_buf_alloc(id, MIN(target_data_len, *BufLen));
|
||||
if (phase == SCSI_PHASE_DATA_OUT)
|
||||
x54x_buf_dma_transfer(req, bit24, target_data_len, 1);
|
||||
scsi_device_command_phase1(id);
|
||||
scsi_device_command_phase1(sd);
|
||||
if (phase == SCSI_PHASE_DATA_IN)
|
||||
x54x_buf_dma_transfer(req, bit24, target_data_len, 0);
|
||||
|
||||
SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK));
|
||||
SenseBufferFree(req, (sd->status != SCSI_STATUS_OK));
|
||||
}
|
||||
} else
|
||||
SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK));
|
||||
SenseBufferFree(req, (sd->status != SCSI_STATUS_OK));
|
||||
|
||||
x54x_set_residue(req, target_data_len);
|
||||
|
||||
@@ -1031,15 +1030,15 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
|
||||
x54x_log("Request complete\n");
|
||||
|
||||
if (SCSIDevices[id].Status == SCSI_STATUS_OK) {
|
||||
if (sd->status == SCSI_STATUS_OK) {
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
} else if (SCSIDevices[id].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
} else if (sd->status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||
}
|
||||
|
||||
x54x_log("SCSIDevices[%02i].Status = %02X\n", id, SCSIDevices[id].Status);
|
||||
x54x_log("scsi_devices[%02i].Status = %02X\n", id, sd->status);
|
||||
}
|
||||
|
||||
|
||||
@@ -1058,6 +1057,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
{
|
||||
Req_t *req = &dev->Req;
|
||||
uint8_t id, lun;
|
||||
scsi_device_t *sd;
|
||||
|
||||
/* Fetch data from the Command Control Block. */
|
||||
DMAPageRead(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32));
|
||||
@@ -1069,6 +1069,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun;
|
||||
|
||||
id = req->TargetID;
|
||||
sd = &scsi_devices[id];
|
||||
lun = req->LUN;
|
||||
if ((id > dev->max_id) || (lun > 7)) {
|
||||
x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun);
|
||||
@@ -1081,10 +1082,10 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
|
||||
x54x_log("Scanning SCSI Target ID %i\n", id);
|
||||
|
||||
SCSIDevices[id].Status = SCSI_STATUS_OK;
|
||||
sd->status = SCSI_STATUS_OK;
|
||||
|
||||
/* If there is no device at ID:0, timeout the selection - the LUN is then checked later. */
|
||||
if (! scsi_device_present(id)) {
|
||||
if (! scsi_device_present(sd)) {
|
||||
x54x_log("SCSI Target ID %i and LUN %i have no device attached\n",id,lun);
|
||||
x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock,
|
||||
CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
@@ -1106,7 +1107,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
}
|
||||
if (req->CmdBlock.common.Opcode == 0x81) {
|
||||
x54x_log("Bus reset opcode\n");
|
||||
scsi_device_reset(id);
|
||||
scsi_device_reset(sd);
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
x54x_log("%s: Callback: Send incoming mailbox\n", dev->name);
|
||||
@@ -1443,7 +1444,7 @@ x54x_reset(x54x_t *dev)
|
||||
|
||||
/* Reset all devices on controller reset. */
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
scsi_device_reset(&scsi_devices[i]);
|
||||
|
||||
if (dev->ven_reset)
|
||||
dev->ven_reset(dev);
|
||||
@@ -1500,7 +1501,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (val & CTRL_SCRST) {
|
||||
/* Reset all devices on SCSI bus reset. */
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
scsi_device_reset(&scsi_devices[i]);
|
||||
}
|
||||
|
||||
if (val & CTRL_IRST) {
|
||||
@@ -1677,7 +1678,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (i == host_id) continue;
|
||||
|
||||
/* TODO: Query device for LUN's. */
|
||||
if (scsi_device_present(i))
|
||||
if (scsi_device_present(&scsi_devices[i]))
|
||||
dev->DataBuf[i] |= 1;
|
||||
}
|
||||
dev->DataReplyLeft = i;
|
||||
@@ -1685,9 +1686,9 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case CMD_RETCONF: /* return Configuration */
|
||||
if (dev->ven_get_dma)
|
||||
dev->DataBuf[0] = (1<<dev->ven_get_dma(dev));
|
||||
dev->DataBuf[0] = (1 << dev->ven_get_dma(dev));
|
||||
else
|
||||
dev->DataBuf[0] = (1<<dev->DmaChannel);
|
||||
dev->DataBuf[0] = (1 << dev->DmaChannel);
|
||||
|
||||
if (dev->ven_get_irq)
|
||||
irq = dev->ven_get_irq(dev);
|
||||
|
||||
Reference in New Issue
Block a user