2017-06-14 03:03:29 +02:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* Handling of the SCSI controllers.
|
|
|
|
|
*
|
2017-10-01 16:29:15 -04:00
|
|
|
* Version: @(#)scsi.c 1.0.6 2017/09/30
|
2017-06-14 03:03:29 +02:00
|
|
|
*
|
2017-08-22 21:28:22 +02:00
|
|
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
|
|
|
|
* Miran Grca, <mgrca8@gmail.com>
|
|
|
|
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
2017-08-24 01:14:39 -04:00
|
|
|
* Copyright 2016,2017 Miran Grca.
|
|
|
|
|
* Copyright 2017 Fred N. van Kempen.
|
2017-06-14 03:03:29 +02:00
|
|
|
*/
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
2016-11-12 15:06:38 +01:00
|
|
|
#include <string.h>
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <wchar.h>
|
2017-08-27 00:58:44 +02:00
|
|
|
#include "../86box.h"
|
|
|
|
|
#include "../ibm.h"
|
|
|
|
|
#include "../timer.h"
|
|
|
|
|
#include "../device.h"
|
2017-09-04 01:52:29 -04:00
|
|
|
#include "../cdrom/cdrom.h"
|
2017-10-01 16:29:15 -04:00
|
|
|
#include "../hdd/hdc.h"
|
2016-11-12 15:06:38 +01:00
|
|
|
#include "scsi.h"
|
2017-05-07 23:42:05 -04:00
|
|
|
#include "scsi_aha154x.h"
|
2017-05-05 01:49:42 +02:00
|
|
|
#include "scsi_buslogic.h"
|
|
|
|
|
|
|
|
|
|
|
2017-08-27 21:46:51 -04:00
|
|
|
scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
|
2017-05-05 01:49:42 +02:00
|
|
|
uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE;
|
|
|
|
|
uint8_t SCSIStatus = SCSI_STATUS_OK;
|
|
|
|
|
uint8_t scsi_cdrom_id = 3; /*common setting*/
|
|
|
|
|
char scsi_fn[SCSI_NUM][512];
|
|
|
|
|
uint16_t scsi_hd_location[SCSI_NUM];
|
|
|
|
|
|
|
|
|
|
int scsi_card_current = 0;
|
|
|
|
|
int scsi_card_last = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
char name[64];
|
|
|
|
|
char internal_name[32];
|
|
|
|
|
device_t *device;
|
2017-06-14 03:03:29 +02:00
|
|
|
void (*reset)(void *p);
|
2017-05-05 01:49:42 +02:00
|
|
|
} SCSI_CARD;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static SCSI_CARD scsi_cards[] = {
|
2017-06-14 03:03:29 +02:00
|
|
|
{ "None", "none", NULL, NULL },
|
|
|
|
|
{ "Adaptec AHA-1540B", "aha1540b", &aha1540b_device, aha_device_reset },
|
|
|
|
|
{ "Adaptec AHA-1542CF", "aha1542cf", &aha1542cf_device, aha_device_reset },
|
|
|
|
|
{ "Adaptec AHA-1640", "aha1640", &aha1640_device, aha_device_reset },
|
2017-08-27 00:58:44 +02:00
|
|
|
{ "BusLogic BT-545C", "bt545c", &buslogic_device, BuslogicDeviceReset },
|
|
|
|
|
{ "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device, BuslogicDeviceReset },
|
2017-06-14 03:03:29 +02:00
|
|
|
{ "", "", NULL, NULL },
|
2017-05-05 01:49:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int scsi_card_available(int card)
|
|
|
|
|
{
|
|
|
|
|
if (scsi_cards[card].device)
|
|
|
|
|
return(device_available(scsi_cards[card].device));
|
|
|
|
|
|
|
|
|
|
return(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *scsi_card_getname(int card)
|
|
|
|
|
{
|
|
|
|
|
return(scsi_cards[card].name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
device_t *scsi_card_getdevice(int card)
|
|
|
|
|
{
|
|
|
|
|
return(scsi_cards[card].device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int scsi_card_has_config(int card)
|
|
|
|
|
{
|
|
|
|
|
if (! scsi_cards[card].device) return(0);
|
|
|
|
|
|
|
|
|
|
return(scsi_cards[card].device->config ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *scsi_card_get_internal_name(int card)
|
|
|
|
|
{
|
|
|
|
|
return(scsi_cards[card].internal_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int scsi_card_get_from_internal_name(char *s)
|
|
|
|
|
{
|
|
|
|
|
int c = 0;
|
|
|
|
|
|
|
|
|
|
while (strlen(scsi_cards[c].internal_name)) {
|
|
|
|
|
if (!strcmp(scsi_cards[c].internal_name, s))
|
|
|
|
|
return(c);
|
|
|
|
|
c++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-23 17:11:59 +01:00
|
|
|
|
2017-08-24 01:14:39 -04:00
|
|
|
void scsi_card_init(void)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-08-22 21:28:22 +02:00
|
|
|
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();
|
|
|
|
|
|
2017-08-27 21:46:51 -04:00
|
|
|
for (i=0; i<SCSI_ID_MAX; i++) {
|
|
|
|
|
for (j=0; j<SCSI_LUN_MAX; j++) {
|
2017-08-24 01:14:39 -04:00
|
|
|
if (scsi_hard_disks[i][j] != 0xff) {
|
|
|
|
|
SCSIDevices[i][j].LunType = SCSI_DISK;
|
2017-08-27 21:46:51 -04:00
|
|
|
} else if (scsi_cdrom_drives[i][j] != 0xff) {
|
2017-08-24 01:14:39 -04:00
|
|
|
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
2017-08-27 21:46:51 -04:00
|
|
|
} else {
|
2017-08-24 01:14:39 -04:00
|
|
|
SCSIDevices[i][j].LunType = SCSI_NONE;
|
2017-08-22 21:28:22 +02:00
|
|
|
}
|
2017-08-24 01:14:39 -04:00
|
|
|
}
|
2017-08-22 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
if (scsi_cards[scsi_card_current].device)
|
|
|
|
|
device_add(scsi_cards[scsi_card_current].device);
|
|
|
|
|
|
|
|
|
|
scsi_card_last = scsi_card_current;
|
|
|
|
|
}
|
2017-01-16 01:49:19 +01:00
|
|
|
|
2016-11-12 15:06:38 +01:00
|
|
|
|
2017-06-14 03:03:29 +02:00
|
|
|
void scsi_card_reset(void)
|
|
|
|
|
{
|
|
|
|
|
void *p = NULL;
|
|
|
|
|
|
2017-08-27 21:46:51 -04:00
|
|
|
if (scsi_cards[scsi_card_current].device) {
|
2017-06-14 03:03:29 +02:00
|
|
|
p = device_get_priv(scsi_cards[scsi_card_current].device);
|
2017-08-27 21:46:51 -04:00
|
|
|
if (p) {
|
|
|
|
|
if (scsi_cards[scsi_card_current].reset) {
|
2017-06-14 03:03:29 +02:00
|
|
|
scsi_cards[scsi_card_current].reset(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
/* Initialization function for the SCSI layer */
|
2017-01-18 21:51:03 +01:00
|
|
|
void SCSIReset(uint8_t id, uint8_t lun)
|
2016-12-23 17:11:59 +01:00
|
|
|
{
|
2017-05-05 01:49:42 +02:00
|
|
|
uint8_t cdrom_id = scsi_cdrom_drives[id][lun];
|
|
|
|
|
uint8_t hdc_id = scsi_hard_disks[id][lun];
|
2016-12-30 00:42:54 +01:00
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
if (hdc_id != 0xff) {
|
|
|
|
|
scsi_hd_reset(cdrom_id);
|
2017-05-06 17:48:33 +02:00
|
|
|
SCSIDevices[id][lun].LunType = SCSI_DISK;
|
2017-05-05 01:49:42 +02:00
|
|
|
} else {
|
2017-08-27 21:46:51 -04:00
|
|
|
if (cdrom_id != 0xff) {
|
2017-01-16 01:49:19 +01:00
|
|
|
cdrom_reset(cdrom_id);
|
2017-01-18 21:51:03 +01:00
|
|
|
SCSIDevices[id][lun].LunType = SCSI_CDROM;
|
2017-08-27 21:46:51 -04:00
|
|
|
} else {
|
2017-01-18 21:51:03 +01:00
|
|
|
SCSIDevices[id][lun].LunType = SCSI_NONE;
|
2016-12-23 17:11:59 +01:00
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
2017-05-29 01:18:32 +02:00
|
|
|
|
2017-08-27 21:46:51 -04:00
|
|
|
if (SCSIDevices[id][lun].CmdBuffer != NULL) {
|
2017-05-29 01:18:32 +02:00
|
|
|
free(SCSIDevices[id][lun].CmdBuffer);
|
|
|
|
|
SCSIDevices[id][lun].CmdBuffer = NULL;
|
|
|
|
|
}
|
2016-12-23 17:11:59 +01:00
|
|
|
}
|