From 47ba911525b7181697168826ca6a2d08614c566d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 22 Aug 2017 21:28:22 +0200 Subject: [PATCH] The AHA-154x code is now converted to use the abstraction layer; Moved SCSI device array building to scsi_card_init() in scsi.c. --- src/scsi.c | 37 ++++++-- src/scsi.h | 22 ++++- src/scsi_aha154x.c | 215 +++++--------------------------------------- src/scsi_buslogic.c | 62 +++---------- src/scsi_device.c | 42 ++++++++- src/scsi_device.h | 7 +- 6 files changed, 132 insertions(+), 253 deletions(-) diff --git a/src/scsi.c b/src/scsi.c index 186a2495a..93513aa5d 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -8,13 +8,14 @@ * * 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: Fred N. van Kempen, - * Original Buslogic version by SA1988 and Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Authors: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 TheCollector1995. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. */ #include #include @@ -108,6 +109,30 @@ int scsi_card_get_from_internal_name(char *s) 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) device_add(scsi_cards[scsi_card_current].device); diff --git a/src/scsi.h b/src/scsi.h index 96d0dc8c7..8c6add567 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -1,6 +1,22 @@ -/* 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, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 TheCollector1995. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + */ #ifndef SCSI_H #define SCSI_H diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 18b8ceb9a..d94f3b379 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -12,7 +12,7 @@ * * 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, * Original Buslogic version by SA1988 and Miran Grca. @@ -35,6 +35,7 @@ #include "device.h" #include "cdrom.h" #include "scsi.h" +#include "scsi_device.h" #include "scsi_disk.h" #include "scsi_aha154x.h" @@ -1217,7 +1218,7 @@ aha_0x01: for (i=0; i<7; i++) { dev->DataBuf[i] = 0x00; for (j=0; j<8; j++) { - if (SCSIDevices[i][j].LunType != SCSI_NONE) + if (scsi_device_present(i, j)) dev->DataBuf[i] |= (1<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; uint8_t temp_sense[256]; if (SenseLength && Copy) { - if (is_hd) - { - scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength); - } - else - { - cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); - } + scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength); /* * 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 -aha_disk_cmd(aha_t *dev) +aha_scsi_cmd(aha_t *dev) { Req_t *req = &dev->Req; uint8_t Id, Lun; - uint8_t hdc_id; - uint8_t hd_phase; uint8_t temp_cdb[12]; uint32_t i; + int target_cdb_len = 12; Id = req->TargetID; 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", - Id, Lun, hdc_id); + if (!scsi_device_valid(Id, Lun)) + fatal("SCSI target on %02i:%02i has disappeared\n", Id, Lun); - 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, 0x00, 12); - if (req->CmdBlock.common.CdbLength <= 12) { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, - req->CmdBlock.common.CdbLength); - } else { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, 12); - } - - /* - * 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); - - SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 1); - - 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 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]); for (i = 1; iCmdBlock.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) { + memset(temp_cdb, 0, target_cdb_len); + if (req->CmdBlock.common.CdbLength <= target_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); + memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_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]); + scsi_device_command(Id, Lun, req->CmdBlock.common.CdbLength, temp_cdb); aha_buf_free(req); - SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0); + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); 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); - 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); aha_buf_free(req); - SenseBufferFree(req, 0, 0); + SenseBufferFree(req, 0); aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); } else { @@ -1650,8 +1520,7 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) req->CmdBlock.common.ControlByte); } - AHA_InOperation = (SCSIDevices[Id][Lun].LunType == SCSI_DISK) ? 0x11 : 1; - pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType); + AHA_InOperation = 1; } } @@ -1778,8 +1647,8 @@ aha_cmd_cb(void *priv) return; } } else if (AHA_InOperation == 1) { - pclog("%s: Callback: Process CD-ROM request\n", dev->name); - aha_cdrom_cmd(dev); + pclog("%s: Callback: Process SCSI request\n", dev->name); + aha_scsi_cmd(dev); aha_mbi(dev); if (dev->Req.CmdBlock.common.Cdb[0] == 0x42) { /* 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) { pclog("%s: Callback: Send incoming mailbox\n", dev->name); 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 { fatal("%s: Invalid callback phase: %i\n", dev->name, AHA_InOperation); } @@ -2060,7 +1925,6 @@ static void * aha_init(int type) { aha_t *dev; - int i, j; uint32_t bios_addr = 0x00000000; int bios = 0; @@ -2138,22 +2002,6 @@ aha_init(int type) } 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_cmd_cb, &AHA_Callback, &AHA_Callback, dev); @@ -2200,7 +2048,6 @@ static void * aha_1640_init(void) { aha_t *dev; - int i, j; dev = malloc(sizeof(aha_t)); memset(dev, 0x00, sizeof(aha_t)); @@ -2213,24 +2060,6 @@ aha_1640_init(void) 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_cmd_cb, &AHA_Callback, &AHA_Callback, dev); diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index dd78f9a4f..e7d6204bf 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -10,7 +10,7 @@ * 0 - BT-542B ISA; * 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, * Miran Grca, @@ -1163,7 +1163,7 @@ BuslogicSCSIBIOSRequestSetup(Buslogic_t *bl, uint8_t *CmdBuf, uint8_t *DataInBuf 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); /* 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[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) { @@ -1413,7 +1413,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[7] = (sector_len >> 8) & 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) { @@ -1437,7 +1437,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[7] = (sector_len >> 8) & 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)); @@ -1459,7 +1459,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[0] = GPCMD_FORMAT_UNIT; 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)); @@ -1505,7 +1505,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[4] = (lba >> 8) & 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; @@ -1522,7 +1522,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[0] = GPCMD_TEST_UNIT_READY; 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)); @@ -1534,7 +1534,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[0] = GPCMD_REZERO_UNIT; 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)); @@ -2278,23 +2278,14 @@ BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) 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 cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN]; - uint8_t hdc_id = scsi_hard_disks[req->TargetID][req->LUN]; uint32_t SenseBufferAddress; uint8_t temp_sense[256]; if (SenseLength && Copy) { - if (is_hd) - { - scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength); - } - else - { - cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); - } + scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength); /* * 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); } - scsi_device_command(req->CmdBlock.common.CdbLength, Id, Lun, temp_cdb); + scsi_device_command(Id, Lun, req->CmdBlock.common.CdbLength, temp_cdb); BuslogicDataBufferFree(req); - BuslogicSenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0); + BuslogicSenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); pclog("Request complete\n"); @@ -2400,7 +2391,7 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb if (!scsi_device_present(Id, Lun)) { pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun); BuslogicDataBufferFree(req); - BuslogicSenseBufferFree(req, 0, 0); + BuslogicSenseBufferFree(req, 0); BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock, CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); } else { @@ -2838,9 +2829,6 @@ BuslogicInit(int chip) { Buslogic_t *bl; - int i = 0; - int j = 0; - bl = malloc(sizeof(Buslogic_t)); memset(bl, 0x00, sizeof(Buslogic_t)); @@ -2894,28 +2882,6 @@ BuslogicInit(int chip) 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, &BuslogicResetCallback, &BuslogicResetCallback, bl); timer_add(BuslogicCommandCallback, diff --git a/src/scsi_device.c b/src/scsi_device.c index a72daa69f..043f2ee32 100644 --- a/src/scsi_device.c +++ b/src/scsi_device.c @@ -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, + * Fred N. van Kempen, + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + */ #include "ibm.h" #include "scsi.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) { 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 lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; diff --git a/src/scsi_device.h b/src/scsi_device.h index c3cda987b..c369cc4e3 100644 --- a/src/scsi_device.h +++ b/src/scsi_device.h @@ -8,7 +8,7 @@ * * 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, * Fred N. van Kempen, @@ -20,6 +20,9 @@ extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun); extern void scsi_device_type_data(uint8_t id, uint8_t lun, 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, uint8_t *cdb, uint8_t *buffer, 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_cdb_length(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);