diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index b6db9e051..5cd4b7287 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -42,37 +42,33 @@ #include <86box/scsi_pcscsi.h> #include <86box/scsi_spock.h> #ifdef WALTJE -# include "scsi_wd33c93.h" +# include "scsi_wd33c93.h" #endif +int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 }; -int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 }; - -static uint8_t next_scsi_bus = 0; - +static uint8_t next_scsi_bus = 0; static const device_t scsi_none_device = { - .name = "None", + .name = "None", .internal_name = "none", - .flags = 0, - .local = 0, - .init = NULL, - .close = NULL, - .reset = NULL, + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; - typedef const struct { - const device_t *device; + const device_t *device; } SCSI_CARD; - static SCSI_CARD scsi_cards[] = { -// clang-format off + // clang-format off { &scsi_none_device, }, { &aha154xa_device, }, { &aha154xb_device, }, @@ -107,79 +103,72 @@ static SCSI_CARD scsi_cards[] = { { &buslogic_445s_device, }, { &buslogic_445c_device, }, { NULL, }, -// clang-format on + // clang-format on }; - void scsi_reset(void) { next_scsi_bus = 0; } - uint8_t scsi_get_bus(void) { uint8_t ret = next_scsi_bus; if (next_scsi_bus >= SCSI_BUS_MAX) - return 0xff; + return 0xff; next_scsi_bus++; return ret; } - int scsi_card_available(int card) { if (scsi_cards[card].device) - return(device_available(scsi_cards[card].device)); + return (device_available(scsi_cards[card].device)); - return(1); + return (1); } - const device_t * scsi_card_getdevice(int card) { - return(scsi_cards[card].device); + return (scsi_cards[card].device); } - int scsi_card_has_config(int card) { - if (! scsi_cards[card].device) return(0); + if (!scsi_cards[card].device) + return (0); - return(device_has_config(scsi_cards[card].device) ? 1 : 0); + return (device_has_config(scsi_cards[card].device) ? 1 : 0); } - char * scsi_card_get_internal_name(int card) { return device_get_internal_name(scsi_cards[card].device); } - int scsi_card_get_from_internal_name(char *s) { int c = 0; while (scsi_cards[c].device != NULL) { - if (!strcmp((char *) scsi_cards[c].device->internal_name, s)) - return(c); - c++; + if (!strcmp((char *) scsi_cards[c].device->internal_name, s)) + return (c); + c++; } - return(0); + return (0); } - void scsi_card_init(void) { @@ -188,16 +177,16 @@ scsi_card_init(void) /* On-board SCSI controllers get the first bus, so if one is present, increase our instance number here. */ if (machine_has_flags(machine, MACHINE_SCSI)) - max--; + max--; - /* Do not initialize any controllers if we have do not have any SCSI +/* Do not initialize any controllers if we have do not have any SCSI bus left. */ if (max > 0) { - for (i = 0; i < max; i++) { - if (!scsi_cards[scsi_card_current[i]].device) - continue; + for (i = 0; i < max; i++) { + if (!scsi_cards[scsi_card_current[i]].device) + continue; - device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1); - } + device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1); + } } } diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 36b0964c2..b94759782 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -44,7 +44,6 @@ #include <86box/scsi_aha154x.h> #include <86box/scsi_x54x.h> - enum { AHA_154xA, AHA_154xB, @@ -54,59 +53,52 @@ enum { AHA_1640 }; +#define CMD_WRITE_EEPROM 0x22 /* UNDOC: Write EEPROM */ +#define CMD_READ_EEPROM 0x23 /* UNDOC: Read EEPROM */ +#define CMD_SHADOW_RAM 0x24 /* UNDOC: BIOS shadow ram */ +#define CMD_BIOS_MBINIT 0x25 /* UNDOC: BIOS mailbox initialization */ +#define CMD_MEMORY_MAP_1 0x26 /* UNDOC: Memory Mapper */ +#define CMD_MEMORY_MAP_2 0x27 /* UNDOC: Memory Mapper */ +#define CMD_EXTBIOS 0x28 /* UNDOC: return extended BIOS info */ +#define CMD_MBENABLE 0x29 /* set mailbox interface enable */ +#define CMD_BIOS_SCSI 0x82 /* start ROM BIOS SCSI command */ - -#define CMD_WRITE_EEPROM 0x22 /* UNDOC: Write EEPROM */ -#define CMD_READ_EEPROM 0x23 /* UNDOC: Read EEPROM */ -#define CMD_SHADOW_RAM 0x24 /* UNDOC: BIOS shadow ram */ -#define CMD_BIOS_MBINIT 0x25 /* UNDOC: BIOS mailbox initialization */ -#define CMD_MEMORY_MAP_1 0x26 /* UNDOC: Memory Mapper */ -#define CMD_MEMORY_MAP_2 0x27 /* UNDOC: Memory Mapper */ -#define CMD_EXTBIOS 0x28 /* UNDOC: return extended BIOS info */ -#define CMD_MBENABLE 0x29 /* set mailbox interface enable */ -#define CMD_BIOS_SCSI 0x82 /* start ROM BIOS SCSI command */ - - -uint16_t aha_ports[] = { +uint16_t aha_ports[] = { 0x0330, 0x0334, 0x0230, 0x0234, 0x0130, 0x0134, 0x0000, 0x0000 }; static uint8_t *aha1542cp_pnp_rom = NULL; - -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t CustomerSignature[20]; - uint8_t uAutoRetry; - uint8_t uBoardSwitches; - uint8_t uChecksum; - uint8_t uUnknown; - addr24 BIOSMailboxAddress; + uint8_t CustomerSignature[20]; + uint8_t uAutoRetry; + uint8_t uBoardSwitches; + uint8_t uChecksum; + uint8_t uUnknown; + addr24 BIOSMailboxAddress; } aha_setup_t; #pragma pack(pop) - #ifdef ENABLE_AHA154X_LOG int aha_do_log = ENABLE_AHA154X_LOG; - static void aha_log(const char *fmt, ...) { va_list ap; if (aha_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define aha_log(fmt, ...) +# define aha_log(fmt, ...) #endif - /* * Write data to the BIOS space. * @@ -120,422 +112,404 @@ aha_log(const char *fmt, ...) static void aha_mem_write(uint32_t addr, uint8_t val, void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; addr &= 0x3fff; if ((addr >= dev->rom_shram) && (dev->shram_mode & 1)) - dev->shadow_ram[addr & (dev->rom_shramsz - 1)] = val; + dev->shadow_ram[addr & (dev->rom_shramsz - 1)] = val; } - static uint8_t aha_mem_read(uint32_t addr, void *priv) { - x54x_t *dev = (x54x_t *)priv; - rom_t *rom = &dev->bios; + x54x_t *dev = (x54x_t *) priv; + rom_t *rom = &dev->bios; addr &= 0x3fff; if ((addr >= dev->rom_shram) && (dev->shram_mode & 2)) - return dev->shadow_ram[addr & (dev->rom_shramsz - 1)]; + return dev->shadow_ram[addr & (dev->rom_shramsz - 1)]; - return(rom->rom[addr]); + return (rom->rom[addr]); } - static uint8_t aha154x_shram(x54x_t *dev, uint8_t cmd) { /* If not supported, give up. */ - if (dev->rom_shram == 0x0000) return(0x04); + if (dev->rom_shram == 0x0000) + return (0x04); /* Bit 0 = Shadow RAM write enable; Bit 1 = Shadow RAM read enable. */ dev->shram_mode = cmd; /* Firmware expects 04 status. */ - return(0x04); + return (0x04); } - static void aha_eeprom_save(x54x_t *dev) { FILE *f; f = nvr_fopen(dev->nvr_path, "wb"); - if (f) - { - fwrite(dev->nvr, 1, NVR_SIZE, f); - fclose(f); - f = NULL; + if (f) { + fwrite(dev->nvr, 1, NVR_SIZE, f); + fclose(f); + f = NULL; } } - static uint8_t -aha154x_eeprom(x54x_t *dev, uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) +aha154x_eeprom(x54x_t *dev, uint8_t cmd, uint8_t arg, uint8_t len, uint8_t off, uint8_t *bufp) { uint8_t r = 0xff; - int c; + int c; aha_log("%s: EEPROM cmd=%02x, arg=%02x len=%d, off=%02x\n", - dev->name, cmd, arg, len, off); + dev->name, cmd, arg, len, off); /* Only if we can handle it.. */ - if (dev->nvr == NULL) return(r); + if (dev->nvr == NULL) + return (r); if (cmd == 0x22) { - /* Write data to the EEPROM. */ - for (c = 0; c < len; c++) - dev->nvr[(off + c) & 0xff] = bufp[c]; - r = 0; + /* Write data to the EEPROM. */ + for (c = 0; c < len; c++) + dev->nvr[(off + c) & 0xff] = bufp[c]; + r = 0; - aha_eeprom_save(dev); + aha_eeprom_save(dev); - if (dev->type == AHA_154xCF) { - if (dev->fdc_address > 0) { - fdc_remove(dev->fdc); - fdc_set_base(dev->fdc, (dev->nvr[0] & EE0_ALTFLOP) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); - } - } + if (dev->type == AHA_154xCF) { + if (dev->fdc_address > 0) { + fdc_remove(dev->fdc); + fdc_set_base(dev->fdc, (dev->nvr[0] & EE0_ALTFLOP) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); + } + } } if (cmd == 0x23) { - /* Read data from the EEPROM. */ - for (c = 0; c < len; c++) - bufp[c] = dev->nvr[(off + c) & 0xff]; - r = len; + /* Read data from the EEPROM. */ + for (c = 0; c < len; c++) + bufp[c] = dev->nvr[(off + c) & 0xff]; + r = len; } - return(r); + return (r); } - /* Map either the main or utility (Select) ROM into the memory space. */ static uint8_t aha154x_mmap(x54x_t *dev, uint8_t cmd) { aha_log("%s: MEMORY cmd=%02x\n", dev->name, cmd); - switch(cmd) { - case 0x26: - /* Disable the mapper, so, set ROM1 active. */ - dev->bios.rom = dev->rom1; - break; + switch (cmd) { + case 0x26: + /* Disable the mapper, so, set ROM1 active. */ + dev->bios.rom = dev->rom1; + break; - case 0x27: - /* Enable the mapper, so, set ROM2 active. */ - dev->bios.rom = dev->rom2; - break; + case 0x27: + /* Enable the mapper, so, set ROM2 active. */ + dev->bios.rom = dev->rom2; + break; } - return(0); + return (0); } - static uint8_t aha_get_host_id(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; return dev->nvr[0] & 0x07; } - static uint8_t aha_get_irq(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; return (dev->nvr[1] & 0x07) + 9; } - static uint8_t aha_get_dma(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; return (dev->nvr[1] >> 4) & 0x07; } - static uint8_t aha_cmd_is_fast(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; if (dev->Command == CMD_BIOS_SCSI) - return 1; + return 1; else - return 0; + return 0; } - static uint8_t aha_fast_cmds(void *p, uint8_t cmd) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; if (cmd == CMD_BIOS_SCSI) { - dev->BIOSMailboxReq++; - return 1; + dev->BIOSMailboxReq++; + return 1; } return 0; } - static uint8_t aha_param_len(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; switch (dev->Command) { - case CMD_BIOS_MBINIT: - /* Same as 0x01 for AHA. */ - return sizeof(MailboxInit_t); - break; + case CMD_BIOS_MBINIT: + /* Same as 0x01 for AHA. */ + return sizeof(MailboxInit_t); + break; - case CMD_SHADOW_RAM: - return 1; - break; + case CMD_SHADOW_RAM: + return 1; + break; - case CMD_WRITE_EEPROM: - return 35; - break; + case CMD_WRITE_EEPROM: + return 35; + break; - case CMD_READ_EEPROM: - return 3; + case CMD_READ_EEPROM: + return 3; - case CMD_MBENABLE: - return 2; + case CMD_MBENABLE: + return 2; - case 0x39: - return 3; + case 0x39: + return 3; - case 0x40: - return 2; + case 0x40: + return 2; - default: - return 0; + default: + return 0; } } - static uint8_t aha_cmds(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; MailboxInit_t *mbi; - if (! dev->CmdParamLeft) { - aha_log("Running Operation Code 0x%02X\n", dev->Command); - switch (dev->Command) { - case CMD_WRITE_EEPROM: /* write EEPROM */ - /* Sent by CF BIOS. */ - dev->DataReplyLeft = - aha154x_eeprom(dev, - dev->Command, - dev->CmdBuf[0], - dev->CmdBuf[1], - dev->CmdBuf[2], - &(dev->CmdBuf[3])); - if (dev->DataReplyLeft == 0xff) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; + if (!dev->CmdParamLeft) { + aha_log("Running Operation Code 0x%02X\n", dev->Command); + switch (dev->Command) { + case CMD_WRITE_EEPROM: /* write EEPROM */ + /* Sent by CF BIOS. */ + dev->DataReplyLeft = aha154x_eeprom(dev, + dev->Command, + dev->CmdBuf[0], + dev->CmdBuf[1], + dev->CmdBuf[2], + &(dev->CmdBuf[3])); + if (dev->DataReplyLeft == 0xff) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; - case CMD_READ_EEPROM: /* read EEPROM */ - /* Sent by CF BIOS. */ - dev->DataReplyLeft = - aha154x_eeprom(dev, - dev->Command, - dev->CmdBuf[0], - dev->CmdBuf[1], - dev->CmdBuf[2], - dev->DataBuf); - if (dev->DataReplyLeft == 0xff) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; + case CMD_READ_EEPROM: /* read EEPROM */ + /* Sent by CF BIOS. */ + dev->DataReplyLeft = aha154x_eeprom(dev, + dev->Command, + dev->CmdBuf[0], + dev->CmdBuf[1], + dev->CmdBuf[2], + dev->DataBuf); + if (dev->DataReplyLeft == 0xff) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; - case CMD_SHADOW_RAM: /* Shadow RAM */ - /* - * For AHA1542CF, this is the command - * to play with the Shadow RAM. BIOS - * gives us one argument (00,02,03) - * and expects a 0x04 back in the INTR - * register. --FvK - */ - /* dev->Interrupt = aha154x_shram(dev,val); */ - dev->Interrupt = aha154x_shram(dev, dev->CmdBuf[0]); - break; + case CMD_SHADOW_RAM: /* Shadow RAM */ + /* + * For AHA1542CF, this is the command + * to play with the Shadow RAM. BIOS + * gives us one argument (00,02,03) + * and expects a 0x04 back in the INTR + * register. --FvK + */ + /* dev->Interrupt = aha154x_shram(dev,val); */ + dev->Interrupt = aha154x_shram(dev, dev->CmdBuf[0]); + break; - case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialization */ - /* Sent by CF BIOS. */ - dev->flags |= X54X_MBX_24BIT; + case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialization */ + /* Sent by CF BIOS. */ + dev->flags |= X54X_MBX_24BIT; - mbi = (MailboxInit_t *)dev->CmdBuf; + mbi = (MailboxInit_t *) dev->CmdBuf; - dev->BIOSMailboxInit = 1; - dev->BIOSMailboxCount = mbi->Count; - dev->BIOSMailboxOutAddr = ADDR_TO_U32(mbi->Address); + dev->BIOSMailboxInit = 1; + dev->BIOSMailboxCount = mbi->Count; + dev->BIOSMailboxOutAddr = ADDR_TO_U32(mbi->Address); - aha_log("Initialize BIOS Mailbox: MBO=0x%08lx, %d entries at 0x%08lx\n", - dev->BIOSMailboxOutAddr, - mbi->Count, - ADDR_TO_U32(mbi->Address)); + aha_log("Initialize BIOS Mailbox: MBO=0x%08lx, %d entries at 0x%08lx\n", + dev->BIOSMailboxOutAddr, + mbi->Count, + ADDR_TO_U32(mbi->Address)); - dev->Status &= ~STAT_INIT; - dev->DataReplyLeft = 0; - break; + dev->Status &= ~STAT_INIT; + dev->DataReplyLeft = 0; + break; - case CMD_MEMORY_MAP_1: /* AHA memory mapper */ - case CMD_MEMORY_MAP_2: /* AHA memory mapper */ - /* Sent by CF BIOS. */ - dev->DataReplyLeft = - aha154x_mmap(dev, dev->Command); - break; + case CMD_MEMORY_MAP_1: /* AHA memory mapper */ + case CMD_MEMORY_MAP_2: /* AHA memory mapper */ + /* Sent by CF BIOS. */ + dev->DataReplyLeft = aha154x_mmap(dev, dev->Command); + break; - case CMD_EXTBIOS: /* Return extended BIOS information */ - dev->DataBuf[0] = 0x08; - dev->DataBuf[1] = dev->Lock; - dev->DataReplyLeft = 2; - break; + case CMD_EXTBIOS: /* Return extended BIOS information */ + dev->DataBuf[0] = 0x08; + dev->DataBuf[1] = dev->Lock; + dev->DataReplyLeft = 2; + break; - case CMD_MBENABLE: /* Mailbox interface enable Command */ - dev->DataReplyLeft = 0; - if (dev->CmdBuf[1] == dev->Lock) { - if (dev->CmdBuf[0] & 1) { - dev->Lock = 1; - } else { - dev->Lock = 0; - } - } - break; + case CMD_MBENABLE: /* Mailbox interface enable Command */ + dev->DataReplyLeft = 0; + if (dev->CmdBuf[1] == dev->Lock) { + if (dev->CmdBuf[0] & 1) { + dev->Lock = 1; + } else { + dev->Lock = 0; + } + } + break; - case 0x2C: /* Detect termination status */ - /* Bits 7,6 are termination status and must be 1,0 for the BIOS to work. */ - dev->DataBuf[0] = 0x40; - dev->DataReplyLeft = 1; - break; + case 0x2C: /* Detect termination status */ + /* Bits 7,6 are termination status and must be 1,0 for the BIOS to work. */ + dev->DataBuf[0] = 0x40; + dev->DataReplyLeft = 1; + break; - case 0x2D: /* ???? - Returns two bytes according to the microcode */ - dev->DataBuf[0] = 0x00; - dev->DataBuf[0] = 0x00; - dev->DataReplyLeft = 2; - break; + case 0x2D: /* ???? - Returns two bytes according to the microcode */ + dev->DataBuf[0] = 0x00; + dev->DataBuf[0] = 0x00; + dev->DataReplyLeft = 2; + break; - case 0x33: /* Send the SCSISelect code decompressor program */ - if (dev->cmd_33_len == 0x0000) { - /* If we are on a controller without this command, return invalid command. */ - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } + case 0x33: /* Send the SCSISelect code decompressor program */ + if (dev->cmd_33_len == 0x0000) { + /* If we are on a controller without this command, return invalid command. */ + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } - /* We have to send (decompressor program length + 2 bytes of little endian size). */ - dev->DataReplyLeft = dev->cmd_33_len + 2; - memset(dev->DataBuf, 0x00, dev->DataReplyLeft); - dev->DataBuf[0] = dev->cmd_33_len & 0xff; - dev->DataBuf[1] = (dev->cmd_33_len >> 8) & 0xff; - memcpy(&(dev->DataBuf[2]), dev->cmd_33_buf, dev->cmd_33_len); - break; + /* We have to send (decompressor program length + 2 bytes of little endian size). */ + dev->DataReplyLeft = dev->cmd_33_len + 2; + memset(dev->DataBuf, 0x00, dev->DataReplyLeft); + dev->DataBuf[0] = dev->cmd_33_len & 0xff; + dev->DataBuf[1] = (dev->cmd_33_len >> 8) & 0xff; + memcpy(&(dev->DataBuf[2]), dev->cmd_33_buf, dev->cmd_33_len); + break; - case 0x39: /* Receive 3 bytes: address high, address low, byte to write to that address. */ - /* Since we are not running the actual microcode, just log the received values - (if logging is enabled) and break. */ - aha_log("aha_cmds(): Command 0x39: %02X -> %02X%02X\n", - dev->CmdBuf[2], dev->CmdBuf[0], dev->CmdBuf[1]); - break; + case 0x39: /* Receive 3 bytes: address high, address low, byte to write to that address. */ + /* Since we are not running the actual microcode, just log the received values + (if logging is enabled) and break. */ + aha_log("aha_cmds(): Command 0x39: %02X -> %02X%02X\n", + dev->CmdBuf[2], dev->CmdBuf[0], dev->CmdBuf[1]); + break; - case 0x40: /* Receive 2 bytes: address high, address low, then return one byte from that - address. */ - aha_log("aha_cmds(): Command 0x40: %02X%02X\n", - dev->CmdBuf[0], dev->CmdBuf[1]); - dev->DataReplyLeft = 1; - dev->DataBuf[0] = 0xff; - break; + case 0x40: /* Receive 2 bytes: address high, address low, then return one byte from that + address. */ + aha_log("aha_cmds(): Command 0x40: %02X%02X\n", + dev->CmdBuf[0], dev->CmdBuf[1]); + dev->DataReplyLeft = 1; + dev->DataBuf[0] = 0xff; + break; - default: - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } + default: + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } } return 0; } - static void aha_setup_data(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; ReplyInquireSetupInformation *ReplyISI; - aha_setup_t *aha_setup; + aha_setup_t *aha_setup; - ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; - aha_setup = (aha_setup_t *)ReplyISI->VendorSpecificData; + ReplyISI = (ReplyInquireSetupInformation *) dev->DataBuf; + aha_setup = (aha_setup_t *) ReplyISI->VendorSpecificData; ReplyISI->fSynchronousInitiationEnabled = dev->sync & 1; - ReplyISI->fParityCheckingEnabled = dev->parity & 1; + ReplyISI->fParityCheckingEnabled = dev->parity & 1; U32_TO_ADDR(aha_setup->BIOSMailboxAddress, dev->BIOSMailboxOutAddr); aha_setup->uChecksum = 0xA3; - aha_setup->uUnknown = 0xC2; + aha_setup->uUnknown = 0xC2; } - static void aha_do_bios_mail(x54x_t *dev) { dev->MailboxIsBIOS = 1; if (!dev->BIOSMailboxCount) { - aha_log("aha_do_bios_mail(): No BIOS Mailboxes\n"); - return; + aha_log("aha_do_bios_mail(): No BIOS Mailboxes\n"); + return; } /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ for (dev->BIOSMailboxOutPosCur = 0; dev->BIOSMailboxOutPosCur < dev->BIOSMailboxCount; dev->BIOSMailboxOutPosCur++) { - if (x54x_mbo_process(dev)) - break; + if (x54x_mbo_process(dev)) + break; } } - static void aha_callback(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; if (dev->BIOSMailboxInit && dev->BIOSMailboxReq) - aha_do_bios_mail(dev); + aha_do_bios_mail(dev); } - static uint8_t aha_mca_read(int port, void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; - return(dev->pos_regs[port & 7]); + return (dev->pos_regs[port & 7]); } - static void aha_mca_write(int port, uint8_t val, void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; /* Save the MCA register value. */ dev->pos_regs[port & 7] = val; @@ -548,37 +522,39 @@ aha_mca_write(int port, uint8_t val, void *priv) dev->Base |= ((dev->pos_regs[3] & 0xc0) ? 0x34 : 0x30); /* Save the new IRQ and DMA channel values. */ - dev->Irq = (dev->pos_regs[4] & 0x07) + 8; + dev->Irq = (dev->pos_regs[4] & 0x07) + 8; dev->DmaChannel = dev->pos_regs[5] & 0x0f; /* Extract the BIOS ROM address info. */ - if (! (dev->pos_regs[2] & 0x80)) switch(dev->pos_regs[3] & 0x38) { - case 0x38: /* [1]=xx11 1xxx */ - dev->rom_addr = 0xDC000; - break; + if (!(dev->pos_regs[2] & 0x80)) + switch (dev->pos_regs[3] & 0x38) { + case 0x38: /* [1]=xx11 1xxx */ + dev->rom_addr = 0xDC000; + break; - case 0x30: /* [1]=xx11 0xxx */ - dev->rom_addr = 0xD8000; - break; + case 0x30: /* [1]=xx11 0xxx */ + dev->rom_addr = 0xD8000; + break; - case 0x28: /* [1]=xx10 1xxx */ - dev->rom_addr = 0xD4000; - break; + case 0x28: /* [1]=xx10 1xxx */ + dev->rom_addr = 0xD4000; + break; - case 0x20: /* [1]=xx10 0xxx */ - dev->rom_addr = 0xD0000; - break; + case 0x20: /* [1]=xx10 0xxx */ + dev->rom_addr = 0xD0000; + break; - case 0x18: /* [1]=xx01 1xxx */ - dev->rom_addr = 0xCC000; - break; + case 0x18: /* [1]=xx01 1xxx */ + dev->rom_addr = 0xCC000; + break; - case 0x10: /* [1]=xx01 0xxx */ - dev->rom_addr = 0xC8000; - break; - } else { - /* Disabled. */ - dev->rom_addr = 0x000000; + case 0x10: /* [1]=xx01 0xxx */ + dev->rom_addr = 0xC8000; + break; + } + else { + /* Disabled. */ + dev->rom_addr = 0x000000; } /* @@ -595,7 +571,7 @@ aha_mca_write(int port, uint8_t val, void *priv) * * SCSI Parity is pos[2]=xxx1xxxx. */ - dev->sync = (dev->pos_regs[4] >> 3) & 1; + dev->sync = (dev->pos_regs[4] >> 3) & 1; dev->parity = (dev->pos_regs[4] >> 4) & 1; /* @@ -609,122 +585,120 @@ aha_mca_write(int port, uint8_t val, void *priv) /* Initialize the device if fully configured. */ if (dev->pos_regs[2] & 0x01) { - /* Card enabled; register (new) I/O handler. */ - x54x_io_set(dev, dev->Base, 4); + /* Card enabled; register (new) I/O handler. */ + x54x_io_set(dev, dev->Base, 4); - /* Reset the device. */ - x54x_reset_ctrl(dev, CTRL_HRST); + /* Reset the device. */ + x54x_reset_ctrl(dev, CTRL_HRST); - /* Enable or disable the BIOS ROM. */ - if (dev->rom_addr != 0x000000) { - mem_mapping_enable(&dev->bios.mapping); - mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); - } + /* Enable or disable the BIOS ROM. */ + if (dev->rom_addr != 0x000000) { + mem_mapping_enable(&dev->bios.mapping); + mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); + } - /* Say hello. */ - aha_log("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", - dev->Base, dev->Irq, dev->DmaChannel, dev->rom_addr, dev->HostID); + /* Say hello. */ + aha_log("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", + dev->Base, dev->Irq, dev->DmaChannel, dev->rom_addr, dev->HostID); } } - static uint8_t aha_mca_feedb(void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; return (dev->pos_regs[2] & 0x01); } - static void aha_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { x54x_t *dev = (x54x_t *) priv; - int i; + int i; switch (ld) { - case 0: - if (dev->Base) { - x54x_io_remove(dev, dev->Base, 4); - dev->Base = 0; - } + case 0: + if (dev->Base) { + x54x_io_remove(dev, dev->Base, 4); + dev->Base = 0; + } - dev->Irq = 0; - dev->DmaChannel = ISAPNP_DMA_DISABLED; - dev->rom_addr = 0; + dev->Irq = 0; + dev->DmaChannel = ISAPNP_DMA_DISABLED; + dev->rom_addr = 0; - mem_mapping_disable(&dev->bios.mapping); + mem_mapping_disable(&dev->bios.mapping); - if (config->activate) { - dev->Base = config->io[0].base; - if (dev->Base != ISAPNP_IO_DISABLED) - x54x_io_set(dev, dev->Base, 4); + if (config->activate) { + dev->Base = config->io[0].base; + if (dev->Base != ISAPNP_IO_DISABLED) + x54x_io_set(dev, dev->Base, 4); - /* - * Patch the ROM BIOS image for stuff Adaptec deliberately - * made hard to understand. Well, maybe not, maybe it was - * their way of handling issues like these at the time.. - * - * Patch 1: emulate the I/O ADDR SW setting by patching a - * byte in the BIOS that indicates the I/O ADDR - * switch setting on the board. - */ - if (dev->rom_ioaddr != 0x0000) { - /* Look up the I/O address in the table. */ - for (i=0; i<8; i++) - if (aha_ports[i] == dev->Base) break; - if (i == 8) { - aha_log("%s: invalid I/O address %04x selected!\n", - dev->name, dev->Base); - return; - } - dev->bios.rom[dev->rom_ioaddr] = (uint8_t)i; - /* Negation of the DIP switches to satify the checksum. */ - dev->bios.rom[dev->rom_ioaddr + 1] = (uint8_t)((i ^ 0xff) + 1); - } + /* + * Patch the ROM BIOS image for stuff Adaptec deliberately + * made hard to understand. Well, maybe not, maybe it was + * their way of handling issues like these at the time.. + * + * Patch 1: emulate the I/O ADDR SW setting by patching a + * byte in the BIOS that indicates the I/O ADDR + * switch setting on the board. + */ + if (dev->rom_ioaddr != 0x0000) { + /* Look up the I/O address in the table. */ + for (i = 0; i < 8; i++) + if (aha_ports[i] == dev->Base) + break; + if (i == 8) { + aha_log("%s: invalid I/O address %04x selected!\n", + dev->name, dev->Base); + return; + } + dev->bios.rom[dev->rom_ioaddr] = (uint8_t) i; + /* Negation of the DIP switches to satify the checksum. */ + dev->bios.rom[dev->rom_ioaddr + 1] = (uint8_t) ((i ^ 0xff) + 1); + } - dev->Irq = config->irq[0].irq; - dev->DmaChannel = config->dma[0].dma; + dev->Irq = config->irq[0].irq; + dev->DmaChannel = config->dma[0].dma; - dev->nvr[1] = (dev->Irq - 9) | (dev->DmaChannel << 4); - aha_eeprom_save(dev); + dev->nvr[1] = (dev->Irq - 9) | (dev->DmaChannel << 4); + aha_eeprom_save(dev); - dev->rom_addr = config->mem[0].base; - if (dev->rom_addr) { - mem_mapping_enable(&dev->bios.mapping); - aha_log("SCSI BIOS set to: %08X-%08X\n", dev->rom_addr, dev->rom_addr + config->mem[0].size - 1); - mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, config->mem[0].size); - } - } + dev->rom_addr = config->mem[0].base; + if (dev->rom_addr) { + mem_mapping_enable(&dev->bios.mapping); + aha_log("SCSI BIOS set to: %08X-%08X\n", dev->rom_addr, dev->rom_addr + config->mem[0].size - 1); + mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, config->mem[0].size); + } + } - break; + break; #ifdef AHA1542CP_FDC - case 1: - if (dev->fdc_address) { - fdc_remove(dev->fdc); - dev->fdc_address = 0; - } + case 1: + if (dev->fdc_address) { + fdc_remove(dev->fdc); + dev->fdc_address = 0; + } - fdc_set_irq(dev->fdc, 0); - fdc_set_dma_ch(dev->fdc, ISAPNP_DMA_DISABLED); + fdc_set_irq(dev->fdc, 0); + fdc_set_dma_ch(dev->fdc, ISAPNP_DMA_DISABLED); - if (config->activate) { - dev->fdc_address = config->io[0].base; - if (dev->fdc_address != ISAPNP_IO_DISABLED) - fdc_set_base(dev->fdc, dev->fdc_address); + if (config->activate) { + dev->fdc_address = config->io[0].base; + if (dev->fdc_address != ISAPNP_IO_DISABLED) + fdc_set_base(dev->fdc, dev->fdc_address); - fdc_set_irq(dev->fdc, config->irq[0].irq); - fdc_set_dma_ch(dev->fdc, config->dma[0].dma); - } + fdc_set_irq(dev->fdc, config->irq[0].irq); + fdc_set_dma_ch(dev->fdc, config->dma[0].dma); + } - break; + break; #endif } } - /* Initialize the board's ROM BIOS. */ static void aha_setbios(x54x_t *dev) @@ -732,17 +706,18 @@ aha_setbios(x54x_t *dev) uint32_t size; uint32_t mask; uint32_t temp; - FILE *f; - int i; + FILE *f; + int i; /* Only if this device has a BIOS ROM. */ - if (dev->bios_path == NULL) return; + if (dev->bios_path == NULL) + return; /* Open the BIOS image file and make sure it exists. */ aha_log("%s: loading BIOS from '%s'\n", dev->name, dev->bios_path); if ((f = rom_fopen(dev->bios_path, "rb")) == NULL) { - aha_log("%s: BIOS ROM not found!\n", dev->name); - return; + aha_log("%s: BIOS ROM not found!\n", dev->name); + return; } /* @@ -752,45 +727,45 @@ aha_setbios(x54x_t *dev) * this special case, we can't: we may need WRITE access to the * memory later on. */ - (void)fseek(f, 0L, SEEK_END); + (void) fseek(f, 0L, SEEK_END); temp = ftell(f); - (void)fseek(f, 0L, SEEK_SET); + (void) fseek(f, 0L, SEEK_SET); /* Load first chunk of BIOS (which is the main BIOS, aka ROM1.) */ dev->rom1 = malloc(ROM_SIZE); (void) !fread(dev->rom1, ROM_SIZE, 1, f); temp -= ROM_SIZE; if (temp > 0) { - dev->rom2 = malloc(ROM_SIZE); - (void) !fread(dev->rom2, ROM_SIZE, 1, f); - temp -= ROM_SIZE; + dev->rom2 = malloc(ROM_SIZE); + (void) !fread(dev->rom2, ROM_SIZE, 1, f); + temp -= ROM_SIZE; } else { - dev->rom2 = NULL; + dev->rom2 = NULL; } if (temp != 0) { - aha_log("%s: BIOS ROM size invalid!\n", dev->name); - free(dev->rom1); - if (dev->rom2 != NULL) - free(dev->rom2); - (void)fclose(f); - return; + aha_log("%s: BIOS ROM size invalid!\n", dev->name); + free(dev->rom1); + if (dev->rom2 != NULL) + free(dev->rom2); + (void) fclose(f); + return; } temp = ftell(f); if (temp > ROM_SIZE) - temp = ROM_SIZE; - (void)fclose(f); + temp = ROM_SIZE; + (void) fclose(f); /* Adjust BIOS size in chunks of 2K, as per BIOS spec. */ size = 0x10000; if (temp <= 0x8000) - size = 0x8000; + size = 0x8000; if (temp <= 0x4000) - size = 0x4000; + size = 0x4000; if (temp <= 0x2000) - size = 0x2000; + size = 0x2000; mask = (size - 1); aha_log("%s: BIOS at 0x%06lX, size %lu, mask %08lx\n", - dev->name, dev->rom_addr, size, mask); + dev->name, dev->rom_addr, size, mask); /* Initialize the ROM entry for this BIOS. */ memset(&dev->bios, 0x00, sizeof(rom_t)); @@ -803,9 +778,9 @@ aha_setbios(x54x_t *dev) /* Map this system into the memory map. */ mem_mapping_add(&dev->bios.mapping, dev->rom_addr, size, - aha_mem_read, NULL, NULL, /* aha_mem_readw, aha_mem_readl, */ - aha_mem_write, NULL, NULL, - dev->bios.rom, MEM_MAPPING_EXTERNAL, dev); + aha_mem_read, NULL, NULL, /* aha_mem_readw, aha_mem_readl, */ + aha_mem_write, NULL, NULL, + dev->bios.rom, MEM_MAPPING_EXTERNAL, dev); mem_mapping_disable(&dev->bios.mapping); /* @@ -818,37 +793,38 @@ aha_setbios(x54x_t *dev) * switch setting on the board. */ if (dev->rom_ioaddr != 0x0000) { - /* Look up the I/O address in the table. */ - for (i=0; i<8; i++) - if (aha_ports[i] == dev->Base) break; - if (i == 8) { - aha_log("%s: invalid I/O address %04x selected!\n", - dev->name, dev->Base); - return; - } - dev->bios.rom[dev->rom_ioaddr] = (uint8_t)i; - /* Negation of the DIP switches to satify the checksum. */ - dev->bios.rom[dev->rom_ioaddr + 1] = (uint8_t)((i ^ 0xff) + 1); + /* Look up the I/O address in the table. */ + for (i = 0; i < 8; i++) + if (aha_ports[i] == dev->Base) + break; + if (i == 8) { + aha_log("%s: invalid I/O address %04x selected!\n", + dev->name, dev->Base); + return; + } + dev->bios.rom[dev->rom_ioaddr] = (uint8_t) i; + /* Negation of the DIP switches to satify the checksum. */ + dev->bios.rom[dev->rom_ioaddr + 1] = (uint8_t) ((i ^ 0xff) + 1); } } - /* Get the SCSISelect code decompressor program from the microcode rom for the AHA-1542CP. */ static void aha_setmcode(x54x_t *dev) { uint32_t temp; - FILE *f; + FILE *f; /* Only if this device has a BIOS ROM. */ - if (dev->mcode_path == NULL) return; + if (dev->mcode_path == NULL) + return; /* Open the microcode image file and make sure it exists. */ aha_log("%s: loading microcode from '%ls'\n", dev->name, dev->bios_path); if ((f = rom_fopen(dev->mcode_path, "rb")) == NULL) { - aha_log("%s: microcode ROM not found!\n", dev->name); - return; + aha_log("%s: microcode ROM not found!\n", dev->name); + return; } /* @@ -858,20 +834,20 @@ aha_setmcode(x54x_t *dev) * this special case, we can't: we may need WRITE access to the * memory later on. */ - (void)fseek(f, 0L, SEEK_END); + (void) fseek(f, 0L, SEEK_END); temp = ftell(f); - (void)fseek(f, 0L, SEEK_SET); + (void) fseek(f, 0L, SEEK_SET); if (temp < (dev->cmd_33_offset + dev->cmd_33_len - 1)) { - aha_log("%s: microcode ROM size invalid!\n", dev->name); - (void)fclose(f); - return; + aha_log("%s: microcode ROM size invalid!\n", dev->name); + (void) fclose(f); + return; } /* Allocate the buffer and then read the real PnP ROM into it. */ if (aha1542cp_pnp_rom != NULL) { - free(aha1542cp_pnp_rom); - aha1542cp_pnp_rom = NULL; + free(aha1542cp_pnp_rom); + aha1542cp_pnp_rom = NULL; } aha1542cp_pnp_rom = (uint8_t *) malloc(dev->pnp_len + 7); fseek(f, dev->pnp_offset, SEEK_SET); @@ -891,29 +867,27 @@ aha_setmcode(x54x_t *dev) fseek(f, dev->cmd_33_offset, SEEK_SET); (void) !fread(dev->cmd_33_buf, dev->cmd_33_len, 1, f); - (void)fclose(f); + (void) fclose(f); } - static void aha_initnvr(x54x_t *dev) { /* Initialize the on-board EEPROM. */ - dev->nvr[0] = dev->HostID; /* SCSI ID 7 */ + dev->nvr[0] = dev->HostID; /* SCSI ID 7 */ dev->nvr[0] |= (0x10 | 0x20 | 0x40); if (dev->fdc_address == FDC_SECONDARY_ADDR) - dev->nvr[0] |= EE0_ALTFLOP; - dev->nvr[1] = dev->Irq-9; /* IRQ15 */ - dev->nvr[1] |= (dev->DmaChannel<<4); /* DMA6 */ - dev->nvr[2] = (EE2_HABIOS | /* BIOS enabled */ - EE2_DYNSCAN | /* scan bus */ - EE2_EXT1G | EE2_RMVOK); /* Imm return on seek */ - dev->nvr[3] = SPEED_50; /* speed 5.0 MB/s */ - dev->nvr[6] = (EE6_TERM | /* host term enable */ - EE6_RSTBUS); /* reset SCSI bus on boot*/ + dev->nvr[0] |= EE0_ALTFLOP; + dev->nvr[1] = dev->Irq - 9; /* IRQ15 */ + dev->nvr[1] |= (dev->DmaChannel << 4); /* DMA6 */ + dev->nvr[2] = (EE2_HABIOS | /* BIOS enabled */ + EE2_DYNSCAN | /* scan bus */ + EE2_EXT1G | EE2_RMVOK); /* Imm return on seek */ + dev->nvr[3] = SPEED_50; /* speed 5.0 MB/s */ + dev->nvr[6] = (EE6_TERM | /* host term enable */ + EE6_RSTBUS); /* reset SCSI bus on boot*/ } - /* Initialize the board's EEPROM (NVR.) */ static void aha_setnvr(x54x_t *dev) @@ -921,42 +895,41 @@ aha_setnvr(x54x_t *dev) FILE *f; /* Only if this device has an EEPROM. */ - if (dev->nvr_path == NULL) return; + if (dev->nvr_path == NULL) + return; /* Allocate and initialize the EEPROM. */ - dev->nvr = (uint8_t *)malloc(NVR_SIZE); + dev->nvr = (uint8_t *) malloc(NVR_SIZE); memset(dev->nvr, 0x00, NVR_SIZE); f = nvr_fopen(dev->nvr_path, "rb"); if (f) { - if (fread(dev->nvr, 1, NVR_SIZE, f) != NVR_SIZE) - fatal("aha_setnvr(): Error reading data\n"); - fclose(f); - f = NULL; + if (fread(dev->nvr, 1, NVR_SIZE, f) != NVR_SIZE) + fatal("aha_setnvr(): Error reading data\n"); + fclose(f); + f = NULL; } else - aha_initnvr(dev); + aha_initnvr(dev); if (dev->type == AHA_154xCF) { - if (dev->fdc_address > 0) { - fdc_remove(dev->fdc); - fdc_set_base(dev->fdc, (dev->nvr[0] & EE0_ALTFLOP) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); - } + if (dev->fdc_address > 0) { + fdc_remove(dev->fdc); + fdc_set_base(dev->fdc, (dev->nvr[0] & EE0_ALTFLOP) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); + } } } - void aha1542cp_close(void *priv) { if (aha1542cp_pnp_rom != NULL) { - free(aha1542cp_pnp_rom); - aha1542cp_pnp_rom = NULL; + free(aha1542cp_pnp_rom); + aha1542cp_pnp_rom = NULL; } x54x_close(priv); } - /* General initialization routine for all boards. */ static void * aha_init(const device_t *info) @@ -964,7 +937,7 @@ aha_init(const device_t *info) x54x_t *dev; /* Call common initializer. */ - dev = x54x_init(info); + dev = x54x_init(info); dev->bus = scsi_get_bus(); /* @@ -974,143 +947,141 @@ aha_init(const device_t *info) * and so any info we get here will be overwritten by the * MCA-assigned values later on! */ - dev->Base = device_get_config_hex16("base"); - dev->Irq = device_get_config_int("irq"); + dev->Base = device_get_config_hex16("base"); + dev->Irq = device_get_config_int("irq"); dev->DmaChannel = device_get_config_int("dma"); - dev->rom_addr = device_get_config_hex20("bios_addr"); + dev->rom_addr = device_get_config_hex20("bios_addr"); if (!(dev->card_bus & DEVICE_MCA)) - dev->fdc_address = device_get_config_hex16("fdc_addr"); + dev->fdc_address = device_get_config_hex16("fdc_addr"); else - dev->fdc_address = 0; - dev->HostID = 7; /* default HA ID */ + dev->fdc_address = 0; + dev->HostID = 7; /* default HA ID */ dev->setup_info_len = sizeof(aha_setup_t); - dev->max_id = 7; - dev->flags = 0; + dev->max_id = 7; + dev->flags = 0; - dev->ven_callback = aha_callback; - dev->ven_cmd_is_fast = aha_cmd_is_fast; - dev->ven_fast_cmds = aha_fast_cmds; + dev->ven_callback = aha_callback; + dev->ven_cmd_is_fast = aha_cmd_is_fast; + dev->ven_fast_cmds = aha_fast_cmds; dev->get_ven_param_len = aha_param_len; - dev->ven_cmds = aha_cmds; - dev->get_ven_data = aha_setup_data; + dev->ven_cmds = aha_cmds; + dev->get_ven_data = aha_setup_data; - dev->mcode_path = NULL; - dev->cmd_33_len = 0x0000; + dev->mcode_path = NULL; + dev->cmd_33_len = 0x0000; dev->cmd_33_offset = 0x0000; memset(dev->cmd_33_buf, 0x00, 4096); strcpy(dev->vendor, "Adaptec"); /* Perform per-board initialization. */ - switch(dev->type) { - case AHA_154xA: - strcpy(dev->name, "AHA-154xA"); - dev->fw_rev = "A003"; /* The 3.07 microcode says A006. */ - dev->bios_path = "roms/scsi/adaptec/aha1540a307.bin"; /*Only for port 0x330*/ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ - dev->HostID = device_get_config_int("hostid"); - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; + switch (dev->type) { + case AHA_154xA: + strcpy(dev->name, "AHA-154xA"); + dev->fw_rev = "A003"; /* The 3.07 microcode says A006. */ + dev->bios_path = "roms/scsi/adaptec/aha1540a307.bin"; /*Only for port 0x330*/ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ + dev->HostID = device_get_config_int("hostid"); + dev->rom_shram = 0x3F80; /* shadow RAM address base */ + dev->rom_shramsz = 128; /* size of shadow RAM */ + dev->ha_bps = 5000000.0; /* normal SCSI */ + break; - case AHA_154xB: - strcpy(dev->name, "AHA-154xB"); - switch(dev->Base) { - case 0x0330: - dev->bios_path = - "roms/scsi/adaptec/aha1540b320_330.bin"; - break; + case AHA_154xB: + strcpy(dev->name, "AHA-154xB"); + switch (dev->Base) { + case 0x0330: + dev->bios_path = "roms/scsi/adaptec/aha1540b320_330.bin"; + break; - case 0x0334: - dev->bios_path = - "roms/scsi/adaptec/aha1540b320_334.bin"; - break; - } - dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ - dev->HostID = device_get_config_int("hostid"); - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; + case 0x0334: + dev->bios_path = "roms/scsi/adaptec/aha1540b320_334.bin"; + break; + } + dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ + dev->HostID = device_get_config_int("hostid"); + dev->rom_shram = 0x3F80; /* shadow RAM address base */ + dev->rom_shramsz = 128; /* size of shadow RAM */ + dev->ha_bps = 5000000.0; /* normal SCSI */ + break; - case AHA_154xC: - strcpy(dev->name, "AHA-154xC"); - dev->bios_path = "roms/scsi/adaptec/aha1542c102.bin"; - dev->nvr_path = "aha1542c.nvr"; - dev->fw_rev = "D001"; - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ - dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ - dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ - dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ - dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; + case AHA_154xC: + strcpy(dev->name, "AHA-154xC"); + dev->bios_path = "roms/scsi/adaptec/aha1542c102.bin"; + dev->nvr_path = "aha1542c.nvr"; + dev->fw_rev = "D001"; + dev->rom_shram = 0x3F80; /* shadow RAM address base */ + dev->rom_shramsz = 128; /* size of shadow RAM */ + dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ + dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ + dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ + dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ + dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ + dev->ha_bps = 5000000.0; /* normal SCSI */ + break; - case AHA_154xCF: - strcpy(dev->name, "AHA-154xCF"); - dev->bios_path = "roms/scsi/adaptec/aha1542cf211.bin"; - dev->nvr_path = "aha1542cf.nvr"; - dev->fw_rev = "E001"; - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ - dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ - dev->flags |= X54X_CDROM_BOOT; - dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ - dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ - dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ - dev->ha_bps = 10000000.0; /* fast SCSI */ - if (dev->fdc_address > 0) - dev->fdc = device_add(&fdc_at_device); - break; + case AHA_154xCF: + strcpy(dev->name, "AHA-154xCF"); + dev->bios_path = "roms/scsi/adaptec/aha1542cf211.bin"; + dev->nvr_path = "aha1542cf.nvr"; + dev->fw_rev = "E001"; + dev->rom_shram = 0x3F80; /* shadow RAM address base */ + dev->rom_shramsz = 128; /* size of shadow RAM */ + dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ + dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ + dev->flags |= X54X_CDROM_BOOT; + dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ + dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ + dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ + dev->ha_bps = 10000000.0; /* fast SCSI */ + if (dev->fdc_address > 0) + dev->fdc = device_add(&fdc_at_device); + break; - case AHA_154xCP: - strcpy(dev->name, "AHA-154xCP"); - dev->bios_path = "roms/scsi/adaptec/aha1542cp102.bin"; - dev->mcode_path = "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12"; - dev->nvr_path = "aha1542cp.nvr"; - dev->fw_rev = "F001"; - dev->rom_shram = 0x3F80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ - dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ - dev->rom_fwhigh = 0x0055; /* firmware version (hi/lo) */ - dev->flags |= X54X_CDROM_BOOT; - dev->flags |= X54X_ISAPNP; - dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ - dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ - dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ - dev->ha_bps = 10000000.0; /* fast SCSI */ - dev->pnp_len = 0x00be; /* length of the PnP ROM */ - dev->pnp_offset = 0x533d; /* offset of the PnP ROM in the microcode ROM */ - dev->cmd_33_len = 0x06dc; /* length of the SCSISelect code expansion routine returned by - SCSI controller command 0x33 */ - dev->cmd_33_offset = 0x7000; /* offset of the SCSISelect code expansion routine in the - microcode ROM */ - aha_setmcode(dev); - if (aha1542cp_pnp_rom) - isapnp_add_card(aha1542cp_pnp_rom, dev->pnp_len + 7, aha_pnp_config_changed, NULL, NULL, NULL, dev); + case AHA_154xCP: + strcpy(dev->name, "AHA-154xCP"); + dev->bios_path = "roms/scsi/adaptec/aha1542cp102.bin"; + dev->mcode_path = "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12"; + dev->nvr_path = "aha1542cp.nvr"; + dev->fw_rev = "F001"; + dev->rom_shram = 0x3F80; /* shadow RAM address base */ + dev->rom_shramsz = 128; /* size of shadow RAM */ + dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ + dev->rom_fwhigh = 0x0055; /* firmware version (hi/lo) */ + dev->flags |= X54X_CDROM_BOOT; + dev->flags |= X54X_ISAPNP; + dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ + dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ + dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ + dev->ha_bps = 10000000.0; /* fast SCSI */ + dev->pnp_len = 0x00be; /* length of the PnP ROM */ + dev->pnp_offset = 0x533d; /* offset of the PnP ROM in the microcode ROM */ + dev->cmd_33_len = 0x06dc; /* length of the SCSISelect code expansion routine returned by + SCSI controller command 0x33 */ + dev->cmd_33_offset = 0x7000; /* offset of the SCSISelect code expansion routine in the + microcode ROM */ + aha_setmcode(dev); + if (aha1542cp_pnp_rom) + isapnp_add_card(aha1542cp_pnp_rom, dev->pnp_len + 7, aha_pnp_config_changed, NULL, NULL, NULL, dev); #ifdef AHA1542CP_FDC - dev->fdc = device_add(&fdc_at_device); + dev->fdc = device_add(&fdc_at_device); #endif - break; + break; - case AHA_1640: - strcpy(dev->name, "AHA-1640"); - dev->bios_path = "roms/scsi/adaptec/aha1640.bin"; - dev->fw_rev = "BB01"; + case AHA_1640: + strcpy(dev->name, "AHA-1640"); + dev->bios_path = "roms/scsi/adaptec/aha1640.bin"; + dev->fw_rev = "BB01"; - dev->flags |= X54X_LBA_BIOS; + dev->flags |= X54X_LBA_BIOS; - /* Enable MCA. */ - dev->pos_regs[0] = 0x1F; /* MCA board ID */ - dev->pos_regs[1] = 0x0F; - mca_add(aha_mca_read, aha_mca_write, aha_mca_feedb, NULL, dev); - dev->ha_bps = 5000000.0; /* normal SCSI */ - break; + /* Enable MCA. */ + dev->pos_regs[0] = 0x1F; /* MCA board ID */ + dev->pos_regs[1] = 0x0F; + mca_add(aha_mca_read, aha_mca_write, aha_mca_feedb, NULL, dev); + dev->ha_bps = 5000000.0; /* normal SCSI */ + break; } /* Initialize ROM BIOS if needed. */ @@ -1120,22 +1091,22 @@ aha_init(const device_t *info) aha_setnvr(dev); if (dev->Base != 0) { - /* Initialize the device. */ - x54x_device_reset(dev); + /* Initialize the device. */ + x54x_device_reset(dev); if (!(dev->card_bus & DEVICE_MCA) && !(dev->flags & X54X_ISAPNP)) { - /* Register our address space. */ - x54x_io_set(dev, dev->Base, 4); + /* Register our address space. */ + x54x_io_set(dev, dev->Base, 4); - /* Enable the memory. */ - if (dev->rom_addr != 0x000000) { - mem_mapping_enable(&dev->bios.mapping); - mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); - } - } + /* Enable the memory. */ + if (dev->rom_addr != 0x000000) { + mem_mapping_enable(&dev->bios.mapping); + mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); + } + } } - return(dev); + return (dev); } // clang-format off @@ -1397,85 +1368,85 @@ static const device_config_t aha_154xcf_config[] = { // clang-format on const device_t aha154xa_device = { - .name = "Adaptec AHA-154xA", + .name = "Adaptec AHA-154xA", .internal_name = "aha154xa", - .flags = DEVICE_ISA | DEVICE_AT, - .local = AHA_154xA, - .init = aha_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = AHA_154xA, + .init = aha_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = aha_154xb_config + .force_redraw = NULL, + .config = aha_154xb_config }; const device_t aha154xb_device = { - .name = "Adaptec AHA-154xB", + .name = "Adaptec AHA-154xB", .internal_name = "aha154xb", - .flags = DEVICE_ISA | DEVICE_AT, - .local = AHA_154xB, - .init = aha_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = AHA_154xB, + .init = aha_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = aha_154xb_config + .force_redraw = NULL, + .config = aha_154xb_config }; const device_t aha154xc_device = { - .name = "Adaptec AHA-154xC", + .name = "Adaptec AHA-154xC", .internal_name = "aha154xc", - .flags = DEVICE_ISA | DEVICE_AT, - .local = AHA_154xC, - .init = aha_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = AHA_154xC, + .init = aha_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = aha_154x_config + .force_redraw = NULL, + .config = aha_154x_config }; const device_t aha154xcf_device = { - .name = "Adaptec AHA-154xCF", + .name = "Adaptec AHA-154xCF", .internal_name = "aha154xcf", - .flags = DEVICE_ISA | DEVICE_AT, - .local = AHA_154xCF, - .init = aha_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = AHA_154xCF, + .init = aha_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = aha_154xcf_config + .force_redraw = NULL, + .config = aha_154xcf_config }; const device_t aha154xcp_device = { - .name = "Adaptec AHA-154xCP", + .name = "Adaptec AHA-154xCP", .internal_name = "aha154xcp", - .flags = DEVICE_ISA | DEVICE_AT, - .local = AHA_154xCP, - .init = aha_init, - .close = aha1542cp_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = AHA_154xCP, + .init = aha_init, + .close = aha1542cp_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t aha1640_device = { - .name = "Adaptec AHA-1640", + .name = "Adaptec AHA-1640", .internal_name = "aha1640", - .flags = DEVICE_MCA, - .local = AHA_1640, - .init = aha_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = AHA_1640, + .init = aha_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 00fda1c89..9a4810412 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -47,65 +47,64 @@ #include <86box/scsi_device.h> #include <86box/scsi_x54x.h> - /* * Auto SCSI structure which is located * in host adapter RAM and contains several * configuration parameters. */ -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t aInternalSignature[2]; - uint8_t cbInformation; - uint8_t aHostAdaptertype[6]; - uint8_t uReserved1; - uint8_t fFloppyEnabled :1, - fFloppySecondary :1, - fLevelSensitiveInterrupt:1, - uReserved2 :2, - uSystemRAMAreForBIOS :3; - uint8_t uDMAChannel :7, - fDMAAutoConfiguration :1, - uIrqChannel :7, - fIrqAutoConfiguration :1; - uint8_t uDMATransferRate; - uint8_t uSCSIId; - uint8_t uSCSIConfiguration; - uint8_t uBusOnDelay; - uint8_t uBusOffDelay; - uint8_t uBIOSConfiguration; - uint16_t u16DeviceEnabledMask; - uint16_t u16WidePermittedMask; - uint16_t u16FastPermittedMask; - uint16_t u16SynchronousPermittedMask; - uint16_t u16DisconnectPermittedMask; - uint16_t u16SendStartUnitCommandMask; - uint16_t u16IgnoreInBIOSScanMask; - unsigned char uPCIInterruptPin : 2; - unsigned char uHostAdapterIoPortAddress : 2; - uint8_t fRoundRobinScheme : 1; - uint8_t fVesaBusSpeedGreaterThan33MHz : 1; - uint8_t fVesaBurstWrite : 1; - uint8_t fVesaBurstRead : 1; + uint8_t aInternalSignature[2]; + uint8_t cbInformation; + uint8_t aHostAdaptertype[6]; + uint8_t uReserved1; + uint8_t fFloppyEnabled : 1, + fFloppySecondary : 1, + fLevelSensitiveInterrupt : 1, + uReserved2 : 2, + uSystemRAMAreForBIOS : 3; + uint8_t uDMAChannel : 7, + fDMAAutoConfiguration : 1, + uIrqChannel : 7, + fIrqAutoConfiguration : 1; + uint8_t uDMATransferRate; + uint8_t uSCSIId; + uint8_t uSCSIConfiguration; + uint8_t uBusOnDelay; + uint8_t uBusOffDelay; + uint8_t uBIOSConfiguration; + uint16_t u16DeviceEnabledMask; + uint16_t u16WidePermittedMask; + uint16_t u16FastPermittedMask; + uint16_t u16SynchronousPermittedMask; + uint16_t u16DisconnectPermittedMask; + uint16_t u16SendStartUnitCommandMask; + uint16_t u16IgnoreInBIOSScanMask; + unsigned char uPCIInterruptPin : 2; + unsigned char uHostAdapterIoPortAddress : 2; + uint8_t fRoundRobinScheme : 1; + uint8_t fVesaBusSpeedGreaterThan33MHz : 1; + uint8_t fVesaBurstWrite : 1; + uint8_t fVesaBurstRead : 1; uint16_t u16UltraPermittedMask; uint32_t uReserved5; uint8_t uReserved6; uint8_t uAutoSCSIMaximumLUN; - uint8_t fReserved7 : 1; - uint8_t fSCAMDominant : 1; - uint8_t fSCAMenabled : 1; - uint8_t fSCAMLevel2 : 1; - unsigned char uReserved8 : 4; - uint8_t fInt13Extension : 1; - uint8_t fReserved9 : 1; - uint8_t fCDROMBoot : 1; - unsigned char uReserved10 : 2; - uint8_t fMultiBoot : 1; - unsigned char uReserved11 : 2; - unsigned char uBootTargetId : 4; - unsigned char uBootChannel : 4; - uint8_t fForceBusDeviceScanningOrder : 1; - unsigned char uReserved12 : 7; + uint8_t fReserved7 : 1; + uint8_t fSCAMDominant : 1; + uint8_t fSCAMenabled : 1; + uint8_t fSCAMLevel2 : 1; + unsigned char uReserved8 : 4; + uint8_t fInt13Extension : 1; + uint8_t fReserved9 : 1; + uint8_t fCDROMBoot : 1; + unsigned char uReserved10 : 2; + uint8_t fMultiBoot : 1; + unsigned char uReserved11 : 2; + unsigned char uBootTargetId : 4; + unsigned char uBootChannel : 4; + uint8_t fForceBusDeviceScanningOrder : 1; + unsigned char uReserved12 : 7; uint16_t u16NonTaggedToAlternateLunPermittedMask; uint16_t u16RenegotiateSyncAfterCheckConditionMask; uint8_t aReserved14[10]; @@ -115,186 +114,180 @@ typedef struct { #pragma pack(pop) /* The local RAM. */ -#pragma pack(push,1) +#pragma pack(push, 1) typedef union { - uint8_t u8View[256]; /* byte view */ - struct { /* structured view */ - uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ - AutoSCSIRam autoSCSIData; /* Auto SCSI structure */ + uint8_t u8View[256]; /* byte view */ + struct { /* structured view */ + uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ + AutoSCSIRam autoSCSIData; /* Auto SCSI structure */ } structured; } HALocalRAM; #pragma pack(pop) /** Structure for the INQUIRE_SETUP_INFORMATION reply. */ -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t uSignature; - uint8_t uCharacterD; - uint8_t uHostBusType; - uint8_t uWideTransferPermittedId0To7; - uint8_t uWideTransfersActiveId0To7; + uint8_t uSignature; + uint8_t uCharacterD; + uint8_t uHostBusType; + uint8_t uWideTransferPermittedId0To7; + uint8_t uWideTransfersActiveId0To7; ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15[8]; - uint8_t uDisconnectPermittedId8To15; - uint8_t uReserved2; - uint8_t uWideTransferPermittedId8To15; - uint8_t uWideTransfersActiveId8To15; + uint8_t uDisconnectPermittedId8To15; + uint8_t uReserved2; + uint8_t uWideTransferPermittedId8To15; + uint8_t uWideTransfersActiveId8To15; } buslogic_setup_t; #pragma pack(pop) /* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t uBusType; - uint8_t uBiosAddress; - uint16_t u16ScatterGatherLimit; - uint8_t cMailbox; - uint32_t uMailboxAddressBase; - uint8_t uReserved1 :2, - fFastEISA :1, - uReserved2 :3, - fLevelSensitiveInterrupt:1, - uReserved3 :1; - uint8_t aFirmwareRevision[3]; - uint8_t fHostWideSCSI :1, - fHostDifferentialSCSI :1, - fHostSupportsSCAM :1, - fHostUltraSCSI :1, - fHostSmartTermination :1, - uReserved4 :3; + uint8_t uBusType; + uint8_t uBiosAddress; + uint16_t u16ScatterGatherLimit; + uint8_t cMailbox; + uint32_t uMailboxAddressBase; + uint8_t uReserved1 : 2, + fFastEISA : 1, + uReserved2 : 3, + fLevelSensitiveInterrupt : 1, + uReserved3 : 1; + uint8_t aFirmwareRevision[3]; + uint8_t fHostWideSCSI : 1, + fHostDifferentialSCSI : 1, + fHostSupportsSCAM : 1, + fHostUltraSCSI : 1, + fHostSmartTermination : 1, + uReserved4 : 3; } ReplyInquireExtendedSetupInformation; #pragma pack(pop) /* Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t IsaIOPort; - uint8_t IRQ; - uint8_t LowByteTerminated :1, - HighByteTerminated :1, - uReserved :2, /* Reserved. */ - JP1 :1, /* Whatever that means. */ - JP2 :1, /* Whatever that means. */ - JP3 :1, /* Whatever that means. */ - InformationIsValid :1; - uint8_t uReserved2; /* Reserved. */ + uint8_t IsaIOPort; + uint8_t IRQ; + uint8_t LowByteTerminated : 1, + HighByteTerminated : 1, + uReserved : 2, /* Reserved. */ + JP1 : 1, /* Whatever that means. */ + JP2 : 1, /* Whatever that means. */ + JP3 : 1, /* Whatever that means. */ + InformationIsValid : 1; + uint8_t uReserved2; /* Reserved. */ } BuslogicPCIInformation_t; #pragma pack(pop) -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { /** Data length. */ - uint32_t DataLength; + uint32_t DataLength; /** Data pointer. */ - uint32_t DataPointer; + uint32_t DataPointer; /** The device the request is sent to. */ - uint8_t TargetId; + uint8_t TargetId; /** The LUN in the device. */ - uint8_t LogicalUnit; + uint8_t LogicalUnit; /** Reserved */ - unsigned char Reserved1 : 3; + unsigned char Reserved1 : 3; /** Data direction for the request. */ - unsigned char DataDirection : 2; + unsigned char DataDirection : 2; /** Reserved */ - unsigned char Reserved2 : 3; + unsigned char Reserved2 : 3; /** Length of the SCSI CDB. */ - uint8_t CDBLength; + uint8_t CDBLength; /** The SCSI CDB. (A CDB can be 12 bytes long.) */ - uint8_t CDB[12]; + uint8_t CDB[12]; } ESCMD; #pragma pack(pop) -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t Count; - uint32_t Address; + uint8_t Count; + uint32_t Address; } MailboxInitExtended_t; #pragma pack(pop) -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - rom_t bios; - int ExtendedLUNCCBFormat; - int fAggressiveRoundRobinMode; - HALocalRAM LocalRAM; - int PCIBase; - int MMIOBase; - int chip; - int has_bios; - uint32_t bios_addr, - bios_size, - bios_mask; - uint8_t AutoSCSIROM[32768]; - uint8_t SCAMData[65536]; + rom_t bios; + int ExtendedLUNCCBFormat; + int fAggressiveRoundRobinMode; + HALocalRAM LocalRAM; + int PCIBase; + int MMIOBase; + int chip; + int has_bios; + uint32_t bios_addr, + bios_size, + bios_mask; + uint8_t AutoSCSIROM[32768]; + uint8_t SCAMData[65536]; } buslogic_data_t; #pragma pack(pop) - enum { CHIP_BUSLOGIC_ISA_542B_1991_12_14, CHIP_BUSLOGIC_ISA_545S_1992_10_05, CHIP_BUSLOGIC_ISA_542BH_1993_05_23, CHIP_BUSLOGIC_ISA_545C_1994_12_01, - CHIP_BUSLOGIC_VLB_445S_1993_11_16, - CHIP_BUSLOGIC_VLB_445C_1994_12_01, + CHIP_BUSLOGIC_VLB_445S_1993_11_16, + CHIP_BUSLOGIC_VLB_445C_1994_12_01, CHIP_BUSLOGIC_MCA_640A_1993_05_23, - CHIP_BUSLOGIC_PCI_958D_1995_12_30 + CHIP_BUSLOGIC_PCI_958D_1995_12_30 }; - #ifdef ENABLE_BUSLOGIC_LOG int buslogic_do_log = ENABLE_BUSLOGIC_LOG; - static void buslogic_log(const char *fmt, ...) { va_list ap; if (buslogic_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define buslogic_log(fmt, ...) +# define buslogic_log(fmt, ...) #endif - static char * BuslogicGetNVRFileName(buslogic_data_t *bl) { - switch(bl->chip) - { - case CHIP_BUSLOGIC_ISA_542B_1991_12_14: - return "bt542b.nvr"; - case CHIP_BUSLOGIC_ISA_545S_1992_10_05: - return "bt545s.nvr"; - case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: - return "bt542bh.nvr"; - case CHIP_BUSLOGIC_ISA_545C_1994_12_01: - return "bt545c.nvr"; - case CHIP_BUSLOGIC_VLB_445S_1993_11_16: - return "bt445s.nvr"; - case CHIP_BUSLOGIC_VLB_445C_1994_12_01: - return "bt445c.nvr"; - case CHIP_BUSLOGIC_MCA_640A_1993_05_23: - return "bt640a.nvr"; - case CHIP_BUSLOGIC_PCI_958D_1995_12_30: - return "bt958d.nvr"; - default: - fatal("Unrecognized BusLogic chip: %i\n", bl->chip); - return NULL; - } + switch (bl->chip) { + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: + return "bt542b.nvr"; + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: + return "bt545s.nvr"; + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + return "bt542bh.nvr"; + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + return "bt545c.nvr"; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: + return "bt445s.nvr"; + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: + return "bt445c.nvr"; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: + return "bt640a.nvr"; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: + return "bt958d.nvr"; + default: + fatal("Unrecognized BusLogic chip: %i\n", bl->chip); + return NULL; + } } - static void BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) { - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + HALocalRAM *HALR = &bl->LocalRAM; memset(&(HALR->structured.autoSCSIData), 0, sizeof(AutoSCSIRam)); @@ -308,290 +301,270 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) HALR->structured.autoSCSIData.aHostAdaptertype[0] = ' '; HALR->structured.autoSCSIData.aHostAdaptertype[5] = ' '; switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542B_1991_12_14: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542B", 4); - break; - case CHIP_BUSLOGIC_ISA_545S_1992_10_05: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545S", 4); - break; - case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542BH", 5); - break; - case CHIP_BUSLOGIC_ISA_545C_1994_12_01: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545C", 4); - break; - case CHIP_BUSLOGIC_VLB_445S_1993_11_16: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445S", 4); - break; - case CHIP_BUSLOGIC_VLB_445C_1994_12_01: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445C", 4); - break; - case CHIP_BUSLOGIC_MCA_640A_1993_05_23: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4); - break; - case CHIP_BUSLOGIC_PCI_958D_1995_12_30: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "958D", 4); - break; + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542B", 4); + break; + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545S", 4); + break; + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542BH", 5); + break; + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545C", 4); + break; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445S", 4); + break; + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445C", 4); + break; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4); + break; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "958D", 4); + break; } HALR->structured.autoSCSIData.fLevelSensitiveInterrupt = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; - HALR->structured.autoSCSIData.uSystemRAMAreForBIOS = 6; + HALR->structured.autoSCSIData.uSystemRAMAreForBIOS = 6; if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - switch(dev->DmaChannel) { - case 5: - HALR->structured.autoSCSIData.uDMAChannel = 1; - break; - case 6: - HALR->structured.autoSCSIData.uDMAChannel = 2; - break; - case 7: - HALR->structured.autoSCSIData.uDMAChannel = 3; - break; - default: - HALR->structured.autoSCSIData.uDMAChannel = 0; - break; - } + switch (dev->DmaChannel) { + case 5: + HALR->structured.autoSCSIData.uDMAChannel = 1; + break; + case 6: + HALR->structured.autoSCSIData.uDMAChannel = 2; + break; + case 7: + HALR->structured.autoSCSIData.uDMAChannel = 3; + break; + default: + HALR->structured.autoSCSIData.uDMAChannel = 0; + break; + } } HALR->structured.autoSCSIData.fDMAAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 1; if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - switch(dev->Irq) { - case 9: - HALR->structured.autoSCSIData.uIrqChannel = 1; - break; - case 10: - HALR->structured.autoSCSIData.uIrqChannel = 2; - break; - case 11: - HALR->structured.autoSCSIData.uIrqChannel = 3; - break; - case 12: - HALR->structured.autoSCSIData.uIrqChannel = 4; - break; - case 14: - HALR->structured.autoSCSIData.uIrqChannel = 5; - break; - case 15: - HALR->structured.autoSCSIData.uIrqChannel = 6; - break; - default: - HALR->structured.autoSCSIData.uIrqChannel = 0; - break; - } + switch (dev->Irq) { + case 9: + HALR->structured.autoSCSIData.uIrqChannel = 1; + break; + case 10: + HALR->structured.autoSCSIData.uIrqChannel = 2; + break; + case 11: + HALR->structured.autoSCSIData.uIrqChannel = 3; + break; + case 12: + HALR->structured.autoSCSIData.uIrqChannel = 4; + break; + case 14: + HALR->structured.autoSCSIData.uIrqChannel = 5; + break; + case 15: + HALR->structured.autoSCSIData.uIrqChannel = 6; + break; + default: + HALR->structured.autoSCSIData.uIrqChannel = 0; + break; + } } HALR->structured.autoSCSIData.fIrqAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 1; HALR->structured.autoSCSIData.uDMATransferRate = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 1; - HALR->structured.autoSCSIData.uSCSIId = 7; + HALR->structured.autoSCSIData.uSCSIId = 7; HALR->structured.autoSCSIData.uSCSIConfiguration = 0x3F; - HALR->structured.autoSCSIData.uBusOnDelay = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 7; - HALR->structured.autoSCSIData.uBusOffDelay = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 4; + HALR->structured.autoSCSIData.uBusOnDelay = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 7; + HALR->structured.autoSCSIData.uBusOffDelay = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 4; HALR->structured.autoSCSIData.uBIOSConfiguration = (bl->has_bios) ? 0x33 : 0x32; if (!safe) - HALR->structured.autoSCSIData.uBIOSConfiguration |= 0x04; + HALR->structured.autoSCSIData.uBIOSConfiguration |= 0x04; - HALR->structured.autoSCSIData.u16DeviceEnabledMask = 0xffff; - HALR->structured.autoSCSIData.u16WidePermittedMask = 0xffff; - HALR->structured.autoSCSIData.u16FastPermittedMask = 0xffff; + HALR->structured.autoSCSIData.u16DeviceEnabledMask = 0xffff; + HALR->structured.autoSCSIData.u16WidePermittedMask = 0xffff; + HALR->structured.autoSCSIData.u16FastPermittedMask = 0xffff; HALR->structured.autoSCSIData.u16DisconnectPermittedMask = 0xffff; - HALR->structured.autoSCSIData.uPCIInterruptPin = PCI_INTA; + HALR->structured.autoSCSIData.uPCIInterruptPin = PCI_INTA; HALR->structured.autoSCSIData.fVesaBusSpeedGreaterThan33MHz = 1; HALR->structured.autoSCSIData.uAutoSCSIMaximumLUN = 7; HALR->structured.autoSCSIData.fForceBusDeviceScanningOrder = 1; - HALR->structured.autoSCSIData.fInt13Extension = safe ? 0 : 1; - HALR->structured.autoSCSIData.fCDROMBoot = safe ? 0 : 1; - HALR->structured.autoSCSIData.fMultiBoot = safe ? 0 : 1; - HALR->structured.autoSCSIData.fRoundRobinScheme = safe ? 1 : 0; /* 1 = aggressive, 0 = strict */ + HALR->structured.autoSCSIData.fInt13Extension = safe ? 0 : 1; + HALR->structured.autoSCSIData.fCDROMBoot = safe ? 0 : 1; + HALR->structured.autoSCSIData.fMultiBoot = safe ? 0 : 1; + HALR->structured.autoSCSIData.fRoundRobinScheme = safe ? 1 : 0; /* 1 = aggressive, 0 = strict */ - HALR->structured.autoSCSIData.uHostAdapterIoPortAddress = 2; /* 0 = primary (330h), 1 = secondary (334h), 2 = disable, 3 = reserved */ + HALR->structured.autoSCSIData.uHostAdapterIoPortAddress = 2; /* 0 = primary (330h), 1 = secondary (334h), 2 = disable, 3 = reserved */ } - static void BuslogicInitializeAutoSCSIRam(x54x_t *dev) { - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + HALocalRAM *HALR = &bl->LocalRAM; FILE *f; f = nvr_fopen(BuslogicGetNVRFileName(bl), "rb"); - if (f) - { - if (fread(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f) != 64) - fatal("BuslogicInitializeAutoSCSIRam(): Error reading data\n"); - fclose(f); - f = NULL; - if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - x54x_io_remove(dev, dev->Base, 4); - switch(HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { - case 0: - dev->Base = 0x330; - break; - case 1: - dev->Base = 0x334; - break; - default: - dev->Base = 0; - break; - } - x54x_io_set(dev, dev->Base, 4); - } - } - else - { - BuslogicAutoSCSIRamSetDefaults(dev, 0); + if (f) { + if (fread(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f) != 64) + fatal("BuslogicInitializeAutoSCSIRam(): Error reading data\n"); + fclose(f); + f = NULL; + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { + x54x_io_remove(dev, dev->Base, 4); + switch (HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { + case 0: + dev->Base = 0x330; + break; + case 1: + dev->Base = 0x334; + break; + default: + dev->Base = 0; + break; + } + x54x_io_set(dev, dev->Base, 4); + } + } else { + BuslogicAutoSCSIRamSetDefaults(dev, 0); } } - static void buslogic_cmd_phase1(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; if ((dev->CmdParam == 2) && (dev->Command == 0x90)) { - dev->CmdParamLeft = dev->CmdBuf[1]; + dev->CmdParamLeft = dev->CmdBuf[1]; } if ((dev->CmdParam == 10) && ((dev->Command == 0x97) || (dev->Command == 0xA7))) { - dev->CmdParamLeft = dev->CmdBuf[6]; - dev->CmdParamLeft <<= 8; - dev->CmdParamLeft |= dev->CmdBuf[7]; - dev->CmdParamLeft <<= 8; - dev->CmdParamLeft |= dev->CmdBuf[8]; + dev->CmdParamLeft = dev->CmdBuf[6]; + dev->CmdParamLeft <<= 8; + dev->CmdParamLeft |= dev->CmdBuf[7]; + dev->CmdParamLeft <<= 8; + dev->CmdParamLeft |= dev->CmdBuf[8]; } if ((dev->CmdParam == 4) && (dev->Command == 0xA9)) { - dev->CmdParamLeft = dev->CmdBuf[3]; - dev->CmdParamLeft <<= 8; - dev->CmdParamLeft |= dev->CmdBuf[2]; + dev->CmdParamLeft = dev->CmdBuf[3]; + dev->CmdParamLeft <<= 8; + dev->CmdParamLeft |= dev->CmdBuf[2]; } } - static uint8_t buslogic_get_host_id(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; HALocalRAM *HALR = &bl->LocalRAM; - if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || - (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || - (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || - (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) - return dev->HostID; + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) + return dev->HostID; else - return HALR->structured.autoSCSIData.uSCSIId; + return HALR->structured.autoSCSIData.uSCSIId; } - static uint8_t buslogic_get_irq(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; uint8_t bl_irq[7] = { 0, 9, 10, 11, 12, 14, 15 }; HALocalRAM *HALR = &bl->LocalRAM; - if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || - (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || - (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || - (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || - (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30)) - return dev->Irq; + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30)) + return dev->Irq; else - return bl_irq[HALR->structured.autoSCSIData.uIrqChannel]; + return bl_irq[HALR->structured.autoSCSIData.uIrqChannel]; } - static uint8_t buslogic_get_dma(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; uint8_t bl_dma[4] = { 0, 5, 6, 7 }; HALocalRAM *HALR = &bl->LocalRAM; if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) - return (dev->Base ? 7 : 0); - else if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || - (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || - (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || - (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) - return dev->DmaChannel; + return (dev->Base ? 7 : 0); + else if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) + return dev->DmaChannel; else - return bl_dma[HALR->structured.autoSCSIData.uDMAChannel]; + return bl_dma[HALR->structured.autoSCSIData.uDMAChannel]; } - static uint8_t buslogic_param_len(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; switch (dev->Command) { - case 0x21: - return 5; - case 0x25: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8F: - case 0x92: - case 0x96: - return 1; - case 0x81: - return sizeof(MailboxInitExtended_t); - case 0x83: - return 12; - case 0x90: - case 0x91: - return 2; - case 0x94: - case 0xFB: - return 3; - case 0x93: /* Valid only for VLB */ - return (bl->chip == CHIP_BUSLOGIC_VLB_445C_1994_12_01 || bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) ? 1 : 0; - case 0x95: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; - case 0x97: /* Valid only for PCI */ - case 0xA7: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 10 : 0; - case 0xA8: /* Valid only for PCI */ - case 0xA9: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 4 : 0; - default: - return 0; + case 0x21: + return 5; + case 0x25: + case 0x8B: + case 0x8C: + case 0x8D: + case 0x8F: + case 0x92: + case 0x96: + return 1; + case 0x81: + return sizeof(MailboxInitExtended_t); + case 0x83: + return 12; + case 0x90: + case 0x91: + return 2; + case 0x94: + case 0xFB: + return 3; + case 0x93: /* Valid only for VLB */ + return (bl->chip == CHIP_BUSLOGIC_VLB_445C_1994_12_01 || bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) ? 1 : 0; + case 0x95: /* Valid only for PCI */ + return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; + case 0x97: /* Valid only for PCI */ + case 0xA7: /* Valid only for PCI */ + return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 10 : 0; + case 0xA8: /* Valid only for PCI */ + case 0xA9: /* Valid only for PCI */ + return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 4 : 0; + default: + return 0; } } - static void BuslogicSCSIBIOSDMATransfer(x54x_t *dev, ESCMD *ESCSICmd, uint8_t TargetID, int dir, int transfer_size) { - uint32_t DataPointer = ESCSICmd->DataPointer; - int DataLength = ESCSICmd->DataLength; - uint32_t Address; - uint32_t TransferLength; + uint32_t DataPointer = ESCSICmd->DataPointer; + int DataLength = ESCSICmd->DataLength; + uint32_t Address; + uint32_t TransferLength; scsi_device_t *sd = &scsi_devices[dev->bus][TargetID]; if (ESCSICmd->DataDirection == 0x03) { - /* Non-data command. */ - buslogic_log("BuslogicSCSIBIOSDMATransfer(): Non-data control byte\n"); - return; + /* Non-data command. */ + buslogic_log("BuslogicSCSIBIOSDMATransfer(): Non-data control byte\n"); + return; } buslogic_log("BuslogicSCSIBIOSDMATransfer(): BIOS Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); @@ -599,39 +572,38 @@ BuslogicSCSIBIOSDMATransfer(x54x_t *dev, ESCMD *ESCSICmd, uint8_t TargetID, int /* 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) && (sd->buffer_length > 0)) { - Address = DataPointer; - TransferLength = MIN(DataLength, sd->buffer_length); + Address = DataPointer; + TransferLength = MIN(DataLength, sd->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); - dma_bm_read(Address, (uint8_t *)sd->sc->temp_buffer, TransferLength, transfer_size); - } 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); - dma_bm_write(Address, (uint8_t *)sd->sc->temp_buffer, TransferLength, transfer_size); - } + if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) { + buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address); + dma_bm_read(Address, (uint8_t *) sd->sc->temp_buffer, TransferLength, transfer_size); + } 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); + dma_bm_write(Address, (uint8_t *) sd->sc->temp_buffer, TransferLength, transfer_size); + } } } - static void BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, uint8_t DataReply) { - ESCMD *ESCSICmd = (ESCMD *)CmdBuf; + ESCMD *ESCSICmd = (ESCMD *) CmdBuf; uint32_t i; - uint8_t temp_cdb[12]; - int target_cdb_len = 12; + uint8_t temp_cdb[12]; + int target_cdb_len = 12; #ifdef ENABLE_BUSLOGIC_LOG uint8_t target_id = 0; #endif - int phase; + int phase; scsi_device_t *sd = &scsi_devices[dev->bus][ESCSICmd->TargetId]; DataInBuf[0] = DataInBuf[1] = 0; if ((ESCSICmd->TargetId > 15) || (ESCSICmd->LogicalUnit > 7)) { - DataInBuf[2] = CCB_INVALID_CCB; - DataInBuf[3] = SCSI_STATUS_OK; - return; + DataInBuf[2] = CCB_INVALID_CCB; + DataInBuf[3] = SCSI_STATUS_OK; + return; } buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId); @@ -639,34 +611,35 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u sd->status = SCSI_STATUS_OK; if (!scsi_device_present(sd) || (ESCSICmd->LogicalUnit > 0)) { - buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId); - DataInBuf[2] = CCB_SELECTION_TIMEOUT; - DataInBuf[3] = SCSI_STATUS_OK; - return; + buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId); + DataInBuf[2] = CCB_SELECTION_TIMEOUT; + DataInBuf[3] = SCSI_STATUS_OK; + return; } else { - buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId); - scsi_device_identify(sd, ESCSICmd->LogicalUnit); + buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId); + scsi_device_identify(sd, ESCSICmd->LogicalUnit); - buslogic_log("Transfer Control %02X\n", ESCSICmd->DataDirection); - buslogic_log("CDB Length %i\n", ESCSICmd->CDBLength); + buslogic_log("Transfer Control %02X\n", ESCSICmd->DataDirection); + buslogic_log("CDB Length %i\n", ESCSICmd->CDBLength); } target_cdb_len = 12; - if (!scsi_device_valid(sd)) 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); buslogic_log("SCSI Cdb[0]=0x%02X\n", ESCSICmd->CDB[0]); for (i = 1; i < ESCSICmd->CDBLength; i++) { - buslogic_log("SCSI Cdb[%i]=%i\n", i, ESCSICmd->CDB[i]); + buslogic_log("SCSI Cdb[%i]=%i\n", i, ESCSICmd->CDB[i]); } memset(temp_cdb, 0, target_cdb_len); if (ESCSICmd->CDBLength <= target_cdb_len) { - memcpy(temp_cdb, ESCSICmd->CDB, ESCSICmd->CDBLength); + memcpy(temp_cdb, ESCSICmd->CDB, ESCSICmd->CDBLength); } else { - memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len); + memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len); } sd->buffer_length = ESCSICmd->DataLength; @@ -675,459 +648,444 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u phase = sd->phase; if (phase != SCSI_PHASE_STATUS) { - BuslogicSCSIBIOSDMATransfer(dev, ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size); - scsi_device_command_phase1(sd); + BuslogicSCSIBIOSDMATransfer(dev, ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size); + scsi_device_command_phase1(sd); } buslogic_log("BIOS Request complete\n"); scsi_device_identify(sd, SCSI_LUN_USE_CDB); if (sd->status == SCSI_STATUS_OK) { - DataInBuf[2] = CCB_COMPLETE; - DataInBuf[3] = SCSI_STATUS_OK; + DataInBuf[2] = CCB_COMPLETE; + DataInBuf[3] = SCSI_STATUS_OK; } else if (scsi_devices[dev->bus][ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) { - DataInBuf[2] = CCB_COMPLETE; - DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION; + DataInBuf[2] = CCB_COMPLETE; + DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION; } dev->DataReplyLeft = DataReply; } - static uint8_t buslogic_cmds(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; HALocalRAM *HALR = &bl->LocalRAM; - FILE *f; - uint16_t TargetsPresentMask = 0; - uint32_t Offset; - int i = 0; - MailboxInitExtended_t *MailboxInitE; + FILE *f; + uint16_t TargetsPresentMask = 0; + uint32_t Offset; + int i = 0; + MailboxInitExtended_t *MailboxInitE; ReplyInquireExtendedSetupInformation *ReplyIESI; - BuslogicPCIInformation_t *ReplyPI; - int cCharsToTransfer; + BuslogicPCIInformation_t *ReplyPI; + int cCharsToTransfer; - buslogic_log("Buslogic cmds = 0x%02x\n", dev->Command); + buslogic_log("Buslogic cmds = 0x%02x\n", dev->Command); switch (dev->Command) { - case 0x20: - dev->DataReplyLeft = 0; - x54x_reset_ctrl(dev, 1); - break; - case 0x21: - if (dev->CmdParam == 1) - dev->CmdParamLeft = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - break; - case 0x23: - memset(dev->DataBuf, 0, 8); - for (i = 8; i < 15; i++) { - dev->DataBuf[i - 8] = 0; - if (scsi_device_present(&scsi_devices[dev->bus][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(&scsi_devices[dev->bus][i]) && (i != buslogic_get_host_id(dev))) - TargetsPresentMask |= (1 << i); - } - dev->DataBuf[0] = TargetsPresentMask & 0xFF; - dev->DataBuf[1] = TargetsPresentMask >> 8; - dev->DataReplyLeft = 2; - break; - case 0x25: - if (dev->CmdBuf[0] == 0) - dev->IrqEnabled = 0; - else - dev->IrqEnabled = 1; - return 1; - case 0x81: - dev->flags &= ~X54X_MBX_24BIT; + case 0x20: + dev->DataReplyLeft = 0; + x54x_reset_ctrl(dev, 1); + break; + case 0x21: + if (dev->CmdParam == 1) + dev->CmdParamLeft = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + break; + case 0x23: + memset(dev->DataBuf, 0, 8); + for (i = 8; i < 15; i++) { + dev->DataBuf[i - 8] = 0; + if (scsi_device_present(&scsi_devices[dev->bus][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(&scsi_devices[dev->bus][i]) && (i != buslogic_get_host_id(dev))) + TargetsPresentMask |= (1 << i); + } + dev->DataBuf[0] = TargetsPresentMask & 0xFF; + dev->DataBuf[1] = TargetsPresentMask >> 8; + dev->DataReplyLeft = 2; + break; + case 0x25: + if (dev->CmdBuf[0] == 0) + dev->IrqEnabled = 0; + else + dev->IrqEnabled = 1; + return 1; + case 0x81: + dev->flags &= ~X54X_MBX_24BIT; - MailboxInitE = (MailboxInitExtended_t *)dev->CmdBuf; + MailboxInitE = (MailboxInitExtended_t *) dev->CmdBuf; - dev->MailboxInit = 1; - dev->MailboxCount = MailboxInitE->Count; - dev->MailboxOutAddr = MailboxInitE->Address; - dev->MailboxInAddr = MailboxInitE->Address + (dev->MailboxCount * sizeof(Mailbox32_t)); + dev->MailboxInit = 1; + dev->MailboxCount = MailboxInitE->Count; + dev->MailboxOutAddr = MailboxInitE->Address; + dev->MailboxInAddr = MailboxInitE->Address + (dev->MailboxCount * sizeof(Mailbox32_t)); - buslogic_log("Buslogic Extended Initialize Mailbox Command\n"); - buslogic_log("Mailbox Out Address=0x%08X\n", dev->MailboxOutAddr); - buslogic_log("Mailbox In Address=0x%08X\n", dev->MailboxInAddr); - buslogic_log("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); + buslogic_log("Buslogic Extended Initialize Mailbox Command\n"); + buslogic_log("Mailbox Out Address=0x%08X\n", dev->MailboxOutAddr); + buslogic_log("Mailbox In Address=0x%08X\n", dev->MailboxInAddr); + buslogic_log("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); - dev->Status &= ~STAT_INIT; - dev->DataReplyLeft = 0; - break; - case 0x83: - if (dev->CmdParam == 12) { - dev->CmdParamLeft = dev->CmdBuf[11]; - buslogic_log("Execute SCSI BIOS Command: %u more bytes follow\n", dev->CmdParamLeft); - } else { - buslogic_log("Execute SCSI BIOS Command: received %u bytes\n", dev->CmdBuf[0]); - BuslogicSCSIBIOSRequestSetup(dev, dev->CmdBuf, dev->DataBuf, 4); - } - break; - case 0x84: - dev->DataBuf[0] = dev->fw_rev[4]; - dev->DataReplyLeft = 1; - break; - case 0x85: - if (strlen(dev->fw_rev) == 6) - dev->DataBuf[0] = dev->fw_rev[5]; - else - dev->DataBuf[0] = ' '; - dev->DataReplyLeft = 1; - break; - case 0x86: - if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - ReplyPI = (BuslogicPCIInformation_t *) dev->DataBuf; - memset(ReplyPI, 0, sizeof(BuslogicPCIInformation_t)); - ReplyPI->InformationIsValid = 0; - switch(dev->Base) { - case 0x330: - ReplyPI->IsaIOPort = 0; - break; - case 0x334: - ReplyPI->IsaIOPort = 1; - break; - case 0x230: - ReplyPI->IsaIOPort = 2; - break; - case 0x234: - ReplyPI->IsaIOPort = 3; - break; - case 0x130: - ReplyPI->IsaIOPort = 4; - break; - case 0x134: - ReplyPI->IsaIOPort = 5; - break; - default: - ReplyPI->IsaIOPort = 6; - break; - } - ReplyPI->IRQ = dev->Irq; - dev->DataReplyLeft = sizeof(BuslogicPCIInformation_t); - } else { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - case 0x8B: - /* The reply length is set by the guest and is found in the first byte of the command buffer. */ - dev->DataReplyLeft = dev->CmdBuf[0]; - memset(dev->DataBuf, 0, dev->DataReplyLeft); - if (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) - i = 5; - else - i = 4; - cCharsToTransfer = MIN(dev->DataReplyLeft, i); + dev->Status &= ~STAT_INIT; + dev->DataReplyLeft = 0; + break; + case 0x83: + if (dev->CmdParam == 12) { + dev->CmdParamLeft = dev->CmdBuf[11]; + buslogic_log("Execute SCSI BIOS Command: %u more bytes follow\n", dev->CmdParamLeft); + } else { + buslogic_log("Execute SCSI BIOS Command: received %u bytes\n", dev->CmdBuf[0]); + BuslogicSCSIBIOSRequestSetup(dev, dev->CmdBuf, dev->DataBuf, 4); + } + break; + case 0x84: + dev->DataBuf[0] = dev->fw_rev[4]; + dev->DataReplyLeft = 1; + break; + case 0x85: + if (strlen(dev->fw_rev) == 6) + dev->DataBuf[0] = dev->fw_rev[5]; + else + dev->DataBuf[0] = ' '; + dev->DataReplyLeft = 1; + break; + case 0x86: + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { + ReplyPI = (BuslogicPCIInformation_t *) dev->DataBuf; + memset(ReplyPI, 0, sizeof(BuslogicPCIInformation_t)); + ReplyPI->InformationIsValid = 0; + switch (dev->Base) { + case 0x330: + ReplyPI->IsaIOPort = 0; + break; + case 0x334: + ReplyPI->IsaIOPort = 1; + break; + case 0x230: + ReplyPI->IsaIOPort = 2; + break; + case 0x234: + ReplyPI->IsaIOPort = 3; + break; + case 0x130: + ReplyPI->IsaIOPort = 4; + break; + case 0x134: + ReplyPI->IsaIOPort = 5; + break; + default: + ReplyPI->IsaIOPort = 6; + break; + } + ReplyPI->IRQ = dev->Irq; + dev->DataReplyLeft = sizeof(BuslogicPCIInformation_t); + } else { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + case 0x8B: + /* The reply length is set by the guest and is found in the first byte of the command buffer. */ + dev->DataReplyLeft = dev->CmdBuf[0]; + memset(dev->DataBuf, 0, dev->DataReplyLeft); + if (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) + i = 5; + else + i = 4; + cCharsToTransfer = MIN(dev->DataReplyLeft, i); - memcpy(dev->DataBuf, &(bl->LocalRAM.structured.autoSCSIData.aHostAdaptertype[1]), cCharsToTransfer); - break; - case 0x8C: - dev->DataReplyLeft = dev->CmdBuf[0]; - memset(dev->DataBuf, 0, dev->DataReplyLeft); - break; - case 0x8D: - dev->DataReplyLeft = dev->CmdBuf[0]; - ReplyIESI = (ReplyInquireExtendedSetupInformation *)dev->DataBuf; - memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); + memcpy(dev->DataBuf, &(bl->LocalRAM.structured.autoSCSIData.aHostAdaptertype[1]), cCharsToTransfer); + break; + case 0x8C: + dev->DataReplyLeft = dev->CmdBuf[0]; + memset(dev->DataBuf, 0, dev->DataReplyLeft); + break; + case 0x8D: + dev->DataReplyLeft = dev->CmdBuf[0]; + ReplyIESI = (ReplyInquireExtendedSetupInformation *) dev->DataBuf; + memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); - switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542B_1991_12_14: - case CHIP_BUSLOGIC_ISA_545S_1992_10_05: - case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: - case CHIP_BUSLOGIC_ISA_545C_1994_12_01: - case CHIP_BUSLOGIC_VLB_445S_1993_11_16: - case CHIP_BUSLOGIC_VLB_445C_1994_12_01: - ReplyIESI->uBusType = 'A'; /* ISA style */ - break; - case CHIP_BUSLOGIC_MCA_640A_1993_05_23: - ReplyIESI->uBusType = 'M'; /* MCA style */ - break; - case CHIP_BUSLOGIC_PCI_958D_1995_12_30: - ReplyIESI->uBusType = 'E'; /* PCI style */ - break; - } - ReplyIESI->uBiosAddress = 0xd8; - ReplyIESI->u16ScatterGatherLimit = 8192; - ReplyIESI->cMailbox = dev->MailboxCount; - ReplyIESI->uMailboxAddressBase = dev->MailboxOutAddr; - ReplyIESI->fHostWideSCSI = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; - if ((bl->chip != CHIP_BUSLOGIC_ISA_542B_1991_12_14) && (bl->chip != CHIP_BUSLOGIC_ISA_545S_1992_10_05) && - (bl->chip != CHIP_BUSLOGIC_ISA_542BH_1993_05_23) && (bl->chip != CHIP_BUSLOGIC_MCA_640A_1993_05_23) && - (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16)) - ReplyIESI->fLevelSensitiveInterrupt = bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; - if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) - ReplyIESI->fHostUltraSCSI = 1; - memcpy(ReplyIESI->aFirmwareRevision, &(dev->fw_rev[strlen(dev->fw_rev) - 3]), sizeof(ReplyIESI->aFirmwareRevision)); - buslogic_log("Return Extended Setup Information: %d\n", dev->CmdBuf[0]); - break; - case 0x8F: - bl->fAggressiveRoundRobinMode = dev->CmdBuf[0] & 1; - buslogic_log("Aggressive Round Robin Mode = %d\n", bl->fAggressiveRoundRobinMode); - dev->DataReplyLeft = 0; - break; - case 0x90: - buslogic_log("Store Local RAM\n"); - Offset = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - memcpy(&(bl->LocalRAM.u8View[Offset]), &(dev->CmdBuf[2]), dev->CmdBuf[1]); + switch (bl->chip) { + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: + ReplyIESI->uBusType = 'A'; /* ISA style */ + break; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: + ReplyIESI->uBusType = 'M'; /* MCA style */ + break; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: + ReplyIESI->uBusType = 'E'; /* PCI style */ + break; + } + ReplyIESI->uBiosAddress = 0xd8; + ReplyIESI->u16ScatterGatherLimit = 8192; + ReplyIESI->cMailbox = dev->MailboxCount; + ReplyIESI->uMailboxAddressBase = dev->MailboxOutAddr; + ReplyIESI->fHostWideSCSI = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; + if ((bl->chip != CHIP_BUSLOGIC_ISA_542B_1991_12_14) && (bl->chip != CHIP_BUSLOGIC_ISA_545S_1992_10_05) && (bl->chip != CHIP_BUSLOGIC_ISA_542BH_1993_05_23) && (bl->chip != CHIP_BUSLOGIC_MCA_640A_1993_05_23) && (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16)) + ReplyIESI->fLevelSensitiveInterrupt = bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) + ReplyIESI->fHostUltraSCSI = 1; + memcpy(ReplyIESI->aFirmwareRevision, &(dev->fw_rev[strlen(dev->fw_rev) - 3]), sizeof(ReplyIESI->aFirmwareRevision)); + buslogic_log("Return Extended Setup Information: %d\n", dev->CmdBuf[0]); + break; + case 0x8F: + bl->fAggressiveRoundRobinMode = dev->CmdBuf[0] & 1; + buslogic_log("Aggressive Round Robin Mode = %d\n", bl->fAggressiveRoundRobinMode); + dev->DataReplyLeft = 0; + break; + case 0x90: + buslogic_log("Store Local RAM\n"); + Offset = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + memcpy(&(bl->LocalRAM.u8View[Offset]), &(dev->CmdBuf[2]), dev->CmdBuf[1]); - dev->DataReply = 0; - break; - case 0x91: - buslogic_log("Fetch Local RAM\n"); - Offset = dev->CmdBuf[0]; - dev->DataReplyLeft = dev->CmdBuf[1]; - memcpy(dev->DataBuf, &(bl->LocalRAM.u8View[Offset]), dev->CmdBuf[1]); + dev->DataReply = 0; + break; + case 0x91: + buslogic_log("Fetch Local RAM\n"); + Offset = dev->CmdBuf[0]; + dev->DataReplyLeft = dev->CmdBuf[1]; + memcpy(dev->DataBuf, &(bl->LocalRAM.u8View[Offset]), dev->CmdBuf[1]); - dev->DataReply = 0; - break; - case 0x93: - if ((bl->chip != CHIP_BUSLOGIC_VLB_445C_1994_12_01) && (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16)) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } - case 0x92: - if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || - (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || - (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || - (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } + dev->DataReply = 0; + break; + case 0x93: + if ((bl->chip != CHIP_BUSLOGIC_VLB_445C_1994_12_01) && (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16)) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } + case 0x92: + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } - dev->DataReplyLeft = 0; + dev->DataReplyLeft = 0; - switch (dev->CmdBuf[0]) { - case 0: - case 2: - BuslogicAutoSCSIRamSetDefaults(dev, 0); - break; - case 3: - BuslogicAutoSCSIRamSetDefaults(dev, 3); - break; - case 1: - f = nvr_fopen(BuslogicGetNVRFileName(bl), "wb"); - if (f) { - fwrite(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f); - fclose(f); - f = NULL; - } - break; - default: - dev->Status |= STAT_INVCMD; - break; - } + switch (dev->CmdBuf[0]) { + case 0: + case 2: + BuslogicAutoSCSIRamSetDefaults(dev, 0); + break; + case 3: + BuslogicAutoSCSIRamSetDefaults(dev, 3); + break; + case 1: + f = nvr_fopen(BuslogicGetNVRFileName(bl), "wb"); + if (f) { + fwrite(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f); + fclose(f); + f = NULL; + } + break; + default: + dev->Status |= STAT_INVCMD; + break; + } - if ((bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) && !(dev->Status & STAT_INVCMD)) { - x54x_io_remove(dev, dev->Base, 4); - switch(HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { - case 0: - dev->Base = 0x330; - break; - case 1: - dev->Base = 0x334; - break; - default: - dev->Base = 0; - break; - } - x54x_io_set(dev, dev->Base, 4); - } - break; - case 0x94: - if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23) || - (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23)) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } + if ((bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) && !(dev->Status & STAT_INVCMD)) { + x54x_io_remove(dev, dev->Base, 4); + switch (HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { + case 0: + dev->Base = 0x330; + break; + case 1: + dev->Base = 0x334; + break; + default: + dev->Base = 0; + break; + } + x54x_io_set(dev, dev->Base, 4); + } + break; + case 0x94: + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23)) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } - if (dev->CmdBuf[0]) { - buslogic_log("Invalid AutoSCSI command mode %x\n", dev->CmdBuf[0]); - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } else { - dev->DataReplyLeft = dev->CmdBuf[2]; - dev->DataReplyLeft <<= 8; - dev->DataReplyLeft |= dev->CmdBuf[1]; - memcpy(dev->DataBuf, bl->AutoSCSIROM, dev->DataReplyLeft); - buslogic_log("Returning AutoSCSI ROM (%04X %04X %04X %04X)\n", dev->DataBuf[0], dev->DataBuf[1], dev->DataBuf[2], dev->DataBuf[3]); - } - break; - case 0x95: - if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - if (dev->Base != 0) - x54x_io_remove(dev, dev->Base, 4); - if (dev->CmdBuf[0] < 6) { - dev->Base = ((3 - (dev->CmdBuf[0] >> 1)) << 8) | ((dev->CmdBuf[0] & 1) ? 0x34 : 0x30); - x54x_io_set(dev, dev->Base, 4); - } else - dev->Base = 0; - dev->DataReplyLeft = 0; - return 1; - } else { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - case 0x96: - if (dev->CmdBuf[0] == 0) - bl->ExtendedLUNCCBFormat = 0; - else if (dev->CmdBuf[0] == 1) - bl->ExtendedLUNCCBFormat = 1; + if (dev->CmdBuf[0]) { + buslogic_log("Invalid AutoSCSI command mode %x\n", dev->CmdBuf[0]); + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } else { + dev->DataReplyLeft = dev->CmdBuf[2]; + dev->DataReplyLeft <<= 8; + dev->DataReplyLeft |= dev->CmdBuf[1]; + memcpy(dev->DataBuf, bl->AutoSCSIROM, dev->DataReplyLeft); + buslogic_log("Returning AutoSCSI ROM (%04X %04X %04X %04X)\n", dev->DataBuf[0], dev->DataBuf[1], dev->DataBuf[2], dev->DataBuf[3]); + } + break; + case 0x95: + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { + if (dev->Base != 0) + x54x_io_remove(dev, dev->Base, 4); + if (dev->CmdBuf[0] < 6) { + dev->Base = ((3 - (dev->CmdBuf[0] >> 1)) << 8) | ((dev->CmdBuf[0] & 1) ? 0x34 : 0x30); + x54x_io_set(dev, dev->Base, 4); + } else + dev->Base = 0; + dev->DataReplyLeft = 0; + return 1; + } else { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + case 0x96: + if (dev->CmdBuf[0] == 0) + bl->ExtendedLUNCCBFormat = 0; + else if (dev->CmdBuf[0] == 1) + bl->ExtendedLUNCCBFormat = 1; - dev->DataReplyLeft = 0; - break; - case 0x97: - case 0xA7: - /* TODO: Actually correctly implement this whole SCSI BIOS Flash stuff. */ - dev->DataReplyLeft = 0; - break; - case 0xA8: - if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } + dev->DataReplyLeft = 0; + break; + case 0x97: + case 0xA7: + /* TODO: Actually correctly implement this whole SCSI BIOS Flash stuff. */ + dev->DataReplyLeft = 0; + break; + case 0xA8: + if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } - Offset = dev->CmdBuf[1]; - Offset <<= 8; - Offset |= dev->CmdBuf[0]; + Offset = dev->CmdBuf[1]; + Offset <<= 8; + Offset |= dev->CmdBuf[0]; - dev->DataReplyLeft = dev->CmdBuf[3]; - dev->DataReplyLeft <<= 8; - dev->DataReplyLeft |= dev->CmdBuf[2]; + dev->DataReplyLeft = dev->CmdBuf[3]; + dev->DataReplyLeft <<= 8; + dev->DataReplyLeft |= dev->CmdBuf[2]; - memcpy(dev->DataBuf, &(bl->SCAMData[Offset]), dev->DataReplyLeft); + memcpy(dev->DataBuf, &(bl->SCAMData[Offset]), dev->DataReplyLeft); - dev->DataReply = 0; - break; - case 0xA9: - if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; - } + dev->DataReply = 0; + break; + case 0xA9: + if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } - Offset = dev->CmdBuf[1]; - Offset <<= 8; - Offset |= dev->CmdBuf[0]; + Offset = dev->CmdBuf[1]; + Offset <<= 8; + Offset |= dev->CmdBuf[0]; - dev->DataReplyLeft = dev->CmdBuf[3]; - dev->DataReplyLeft <<= 8; - dev->DataReplyLeft |= dev->CmdBuf[2]; + dev->DataReplyLeft = dev->CmdBuf[3]; + dev->DataReplyLeft <<= 8; + dev->DataReplyLeft |= dev->CmdBuf[2]; - memcpy(&(bl->SCAMData[Offset]), &(dev->CmdBuf[4]), dev->DataReplyLeft); - dev->DataReplyLeft = 0; + memcpy(&(bl->SCAMData[Offset]), &(dev->CmdBuf[4]), dev->DataReplyLeft); + dev->DataReplyLeft = 0; - dev->DataReply = 0; - break; - case 0xFB: - dev->DataReplyLeft = dev->CmdBuf[2]; - break; - default: - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - break; + dev->DataReply = 0; + break; + case 0xFB: + dev->DataReplyLeft = dev->CmdBuf[2]; + break; + default: + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; } return 0; } - static void buslogic_setup_data(void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; ReplyInquireSetupInformation *ReplyISI; - buslogic_setup_t *bl_setup; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + buslogic_setup_t *bl_setup; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + HALocalRAM *HALR = &bl->LocalRAM; - ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; - bl_setup = (buslogic_setup_t *)ReplyISI->VendorSpecificData; + ReplyISI = (ReplyInquireSetupInformation *) dev->DataBuf; + bl_setup = (buslogic_setup_t *) ReplyISI->VendorSpecificData; ReplyISI->fSynchronousInitiationEnabled = HALR->structured.autoSCSIData.u16SynchronousPermittedMask ? 1 : 0; - ReplyISI->fParityCheckingEnabled = (HALR->structured.autoSCSIData.uSCSIConfiguration & 2) ? 1 : 0; + ReplyISI->fParityCheckingEnabled = (HALR->structured.autoSCSIData.uSCSIConfiguration & 2) ? 1 : 0; bl_setup->uSignature = 'B'; /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too * friendly with Adaptec hardware and upsetting the HBA state. - */ - bl_setup->uCharacterD = 'D'; /* BusLogic model. */ - switch(bl->chip) - { - case CHIP_BUSLOGIC_ISA_542B_1991_12_14: - case CHIP_BUSLOGIC_ISA_545S_1992_10_05: - case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: - case CHIP_BUSLOGIC_ISA_545C_1994_12_01: - bl_setup->uHostBusType = 'A'; - break; - case CHIP_BUSLOGIC_MCA_640A_1993_05_23: - bl_setup->uHostBusType = 'B'; - break; - case CHIP_BUSLOGIC_VLB_445S_1993_11_16: - case CHIP_BUSLOGIC_VLB_445C_1994_12_01: - bl_setup->uHostBusType = 'E'; - break; - case CHIP_BUSLOGIC_PCI_958D_1995_12_30: - bl_setup->uHostBusType = 'F'; - break; + */ + bl_setup->uCharacterD = 'D'; /* BusLogic model. */ + switch (bl->chip) { + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + bl_setup->uHostBusType = 'A'; + break; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: + bl_setup->uHostBusType = 'B'; + break; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: + bl_setup->uHostBusType = 'E'; + break; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: + bl_setup->uHostBusType = 'F'; + break; } } - static uint8_t buslogic_is_aggressive_mode(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - buslogic_log("Buslogic: Aggressive mode = %d\n", bl->fAggressiveRoundRobinMode); + buslogic_log("Buslogic: Aggressive mode = %d\n", bl->fAggressiveRoundRobinMode); return bl->fAggressiveRoundRobinMode; } - static uint8_t buslogic_interrupt_type(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || - (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) - return 0; + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) + return 0; else - return !!bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; + return !!bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; } - static void buslogic_reset(void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; bl->ExtendedLUNCCBFormat = 0; } - -uint8_t buslogic_pci_regs[256]; -bar_t buslogic_pci_bar[3]; - +uint8_t buslogic_pci_regs[256]; +bar_t buslogic_pci_bar[3]; static void BuslogicBIOSUpdate(buslogic_data_t *bl) @@ -1135,25 +1093,25 @@ BuslogicBIOSUpdate(buslogic_data_t *bl) int bios_enabled = buslogic_pci_bar[2].addr_regs[0] & 0x01; if (!bl->has_bios) { - return; + return; } /* PCI BIOS stuff, just enable_disable. */ if ((bl->bios_addr > 0) && bios_enabled) { - mem_mapping_enable(&bl->bios.mapping); - mem_mapping_set_addr(&bl->bios.mapping, - bl->bios_addr, bl->bios_size); - buslogic_log("BT-958D: BIOS now at: %06X\n", bl->bios_addr); + mem_mapping_enable(&bl->bios.mapping); + mem_mapping_set_addr(&bl->bios.mapping, + bl->bios_addr, bl->bios_size); + buslogic_log("BT-958D: BIOS now at: %06X\n", bl->bios_addr); } else { - buslogic_log("BT-958D: BIOS disabled\n"); - mem_mapping_disable(&bl->bios.mapping); + buslogic_log("BT-958D: BIOS disabled\n"); + mem_mapping_disable(&bl->bios.mapping); } } static uint8_t BuslogicPCIRead(int func, int addr, void *p) { - x54x_t *dev = (x54x_t *)p; + x54x_t *dev = (x54x_t *) p; #ifdef ENABLE_BUSLOGIC_LOG buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; #endif @@ -1161,218 +1119,219 @@ BuslogicPCIRead(int func, int addr, void *p) buslogic_log("BT-958D: Reading register %02X\n", addr & 0xff); switch (addr) { - case 0x00: - return 0x4b; - case 0x01: - return 0x10; - case 0x02: - return 0x40; - case 0x03: - return 0x10; - case 0x04: - return buslogic_pci_regs[0x04] & 0x03; /*Respond to IO and memory accesses*/ - case 0x05: - return 0; - case 0x07: - return 2; - case 0x08: - return 1; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - case 0x0A: - return 0; /*Subclass*/ - case 0x0B: - return 1; /*Class code*/ - case 0x0E: - return 0; /*Header type */ - case 0x10: - return (buslogic_pci_bar[0].addr_regs[0] & 0xe0) | 1; /*I/O space*/ - case 0x11: - return buslogic_pci_bar[0].addr_regs[1]; - case 0x12: - return buslogic_pci_bar[0].addr_regs[2]; - case 0x13: - return buslogic_pci_bar[0].addr_regs[3]; - case 0x14: - // return (buslogic_pci_bar[1].addr_regs[0] & 0xe0); /*Memory space*/ - return 0x00; - case 0x15: - return buslogic_pci_bar[1].addr_regs[1] & 0xc0; - case 0x16: - return buslogic_pci_bar[1].addr_regs[2]; - case 0x17: - return buslogic_pci_bar[1].addr_regs[3]; - case 0x2C: - return 0x4b; - case 0x2D: - return 0x10; - case 0x2E: - return 0x40; - case 0x2F: - return 0x10; - case 0x30: /* PCI_ROMBAR */ - buslogic_log("BT-958D: BIOS BAR 00 = %02X\n", buslogic_pci_bar[2].addr_regs[0] & 0x01); - return buslogic_pci_bar[2].addr_regs[0] & 0x01; - case 0x31: /* PCI_ROMBAR 15:11 */ - buslogic_log("BT-958D: BIOS BAR 01 = %02X\n", (buslogic_pci_bar[2].addr_regs[1] & bl->bios_mask)); - return buslogic_pci_bar[2].addr_regs[1]; - break; - case 0x32: /* PCI_ROMBAR 23:16 */ - buslogic_log("BT-958D: BIOS BAR 02 = %02X\n", buslogic_pci_bar[2].addr_regs[2]); - return buslogic_pci_bar[2].addr_regs[2]; - break; - case 0x33: /* PCI_ROMBAR 31:24 */ - buslogic_log("BT-958D: BIOS BAR 03 = %02X\n", buslogic_pci_bar[2].addr_regs[3]); - return buslogic_pci_bar[2].addr_regs[3]; - break; - case 0x3C: - return dev->Irq; - case 0x3D: - return PCI_INTA; + case 0x00: + return 0x4b; + case 0x01: + return 0x10; + case 0x02: + return 0x40; + case 0x03: + return 0x10; + case 0x04: + return buslogic_pci_regs[0x04] & 0x03; /*Respond to IO and memory accesses*/ + case 0x05: + return 0; + case 0x07: + return 2; + case 0x08: + return 1; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0A: + return 0; /*Subclass*/ + case 0x0B: + return 1; /*Class code*/ + case 0x0E: + return 0; /*Header type */ + case 0x10: + return (buslogic_pci_bar[0].addr_regs[0] & 0xe0) | 1; /*I/O space*/ + case 0x11: + return buslogic_pci_bar[0].addr_regs[1]; + case 0x12: + return buslogic_pci_bar[0].addr_regs[2]; + case 0x13: + return buslogic_pci_bar[0].addr_regs[3]; + case 0x14: + // return (buslogic_pci_bar[1].addr_regs[0] & 0xe0); /*Memory space*/ + return 0x00; + case 0x15: + return buslogic_pci_bar[1].addr_regs[1] & 0xc0; + case 0x16: + return buslogic_pci_bar[1].addr_regs[2]; + case 0x17: + return buslogic_pci_bar[1].addr_regs[3]; + case 0x2C: + return 0x4b; + case 0x2D: + return 0x10; + case 0x2E: + return 0x40; + case 0x2F: + return 0x10; + case 0x30: /* PCI_ROMBAR */ + buslogic_log("BT-958D: BIOS BAR 00 = %02X\n", buslogic_pci_bar[2].addr_regs[0] & 0x01); + return buslogic_pci_bar[2].addr_regs[0] & 0x01; + case 0x31: /* PCI_ROMBAR 15:11 */ + buslogic_log("BT-958D: BIOS BAR 01 = %02X\n", (buslogic_pci_bar[2].addr_regs[1] & bl->bios_mask)); + return buslogic_pci_bar[2].addr_regs[1]; + break; + case 0x32: /* PCI_ROMBAR 23:16 */ + buslogic_log("BT-958D: BIOS BAR 02 = %02X\n", buslogic_pci_bar[2].addr_regs[2]); + return buslogic_pci_bar[2].addr_regs[2]; + break; + case 0x33: /* PCI_ROMBAR 31:24 */ + buslogic_log("BT-958D: BIOS BAR 03 = %02X\n", buslogic_pci_bar[2].addr_regs[3]); + return buslogic_pci_bar[2].addr_regs[3]; + break; + case 0x3C: + return dev->Irq; + case 0x3D: + return PCI_INTA; } - return(0); + return (0); } - static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) { - x54x_t *dev = (x54x_t *)p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; uint8_t valxor; buslogic_log("BT-958D: Write value %02X to register %02X\n", val, addr & 0xff); switch (addr) { - case 0x04: - valxor = (val & 0x27) ^ buslogic_pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) { - x54x_io_remove(dev, bl->PCIBase, 32); - if ((bl->PCIBase != 0) && (val & PCI_COMMAND_IO)) { - x54x_io_set(dev, bl->PCIBase, 32); - } - } - if (valxor & PCI_COMMAND_MEM) { - x54x_mem_disable(dev); - if ((bl->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) { - x54x_mem_set_addr(dev, bl->MMIOBase); - } - } - buslogic_pci_regs[addr] = val & 0x27; - break; + case 0x04: + valxor = (val & 0x27) ^ buslogic_pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) { + x54x_io_remove(dev, bl->PCIBase, 32); + if ((bl->PCIBase != 0) && (val & PCI_COMMAND_IO)) { + x54x_io_set(dev, bl->PCIBase, 32); + } + } + if (valxor & PCI_COMMAND_MEM) { + x54x_mem_disable(dev); + if ((bl->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) { + x54x_mem_set_addr(dev, bl->MMIOBase); + } + } + buslogic_pci_regs[addr] = val & 0x27; + break; - case 0x10: - val &= 0xe0; - val |= 1; - /*FALLTHROUGH*/ + case 0x10: + val &= 0xe0; + val |= 1; + /*FALLTHROUGH*/ - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O. */ - x54x_io_remove(dev, bl->PCIBase, 32); - /* Then let's set the PCI regs. */ - buslogic_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - bl->PCIBase = buslogic_pci_bar[0].addr & 0xffe0; - /* Log the new base. */ - buslogic_log("BusLogic PCI: New I/O base is %04X\n" , bl->PCIBase); - /* We're done, so get out of the here. */ - if (buslogic_pci_regs[4] & PCI_COMMAND_IO) { - if (bl->PCIBase != 0) { - x54x_io_set(dev, bl->PCIBase, 32); - } - } - return; + case 0x11: + case 0x12: + case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O. */ + x54x_io_remove(dev, bl->PCIBase, 32); + /* Then let's set the PCI regs. */ + buslogic_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + bl->PCIBase = buslogic_pci_bar[0].addr & 0xffe0; + /* Log the new base. */ + buslogic_log("BusLogic PCI: New I/O base is %04X\n", bl->PCIBase); + /* We're done, so get out of the here. */ + if (buslogic_pci_regs[4] & PCI_COMMAND_IO) { + if (bl->PCIBase != 0) { + x54x_io_set(dev, bl->PCIBase, 32); + } + } + return; - case 0x14: - val &= 0xe0; - /*FALLTHROUGH*/ + case 0x14: + val &= 0xe0; + /*FALLTHROUGH*/ - case 0x15: case 0x16: case 0x17: - /* MMIO Base set. */ - /* First, remove the old I/O. */ - x54x_mem_disable(dev); - /* Then let's set the PCI regs. */ - buslogic_pci_bar[1].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - // bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; - /* Give it a 4 kB alignment as that's this emulator's granularity. */ - buslogic_pci_bar[1].addr &= 0xffffc000; - bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffc000; - /* Log the new base. */ - buslogic_log("BusLogic PCI: New MMIO base is %04X\n" , bl->MMIOBase); - /* We're done, so get out of the here. */ - if (buslogic_pci_regs[4] & PCI_COMMAND_MEM) { - if (bl->MMIOBase != 0) { - x54x_mem_set_addr(dev, bl->MMIOBase); - } - } - return; + case 0x15: + case 0x16: + case 0x17: + /* MMIO Base set. */ + /* First, remove the old I/O. */ + x54x_mem_disable(dev); + /* Then let's set the PCI regs. */ + buslogic_pci_bar[1].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + // bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; + /* Give it a 4 kB alignment as that's this emulator's granularity. */ + buslogic_pci_bar[1].addr &= 0xffffc000; + bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffc000; + /* Log the new base. */ + buslogic_log("BusLogic PCI: New MMIO base is %04X\n", bl->MMIOBase); + /* We're done, so get out of the here. */ + if (buslogic_pci_regs[4] & PCI_COMMAND_MEM) { + if (bl->MMIOBase != 0) { + x54x_mem_set_addr(dev, bl->MMIOBase); + } + } + return; - case 0x30: /* PCI_ROMBAR */ - case 0x31: /* PCI_ROMBAR */ - case 0x32: /* PCI_ROMBAR */ - case 0x33: /* PCI_ROMBAR */ - buslogic_pci_bar[2].addr_regs[addr & 3] = val; - buslogic_pci_bar[2].addr &= 0xffffc001; - bl->bios_addr = buslogic_pci_bar[2].addr & 0xffffc000; - buslogic_log("BT-958D: BIOS BAR %02X = NOW %02X (%02X)\n", addr & 3, buslogic_pci_bar[2].addr_regs[addr & 3], val); - BuslogicBIOSUpdate(bl); - return; + case 0x30: /* PCI_ROMBAR */ + case 0x31: /* PCI_ROMBAR */ + case 0x32: /* PCI_ROMBAR */ + case 0x33: /* PCI_ROMBAR */ + buslogic_pci_bar[2].addr_regs[addr & 3] = val; + buslogic_pci_bar[2].addr &= 0xffffc001; + bl->bios_addr = buslogic_pci_bar[2].addr & 0xffffc000; + buslogic_log("BT-958D: BIOS BAR %02X = NOW %02X (%02X)\n", addr & 3, buslogic_pci_bar[2].addr_regs[addr & 3], val); + BuslogicBIOSUpdate(bl); + return; - case 0x3C: - buslogic_pci_regs[addr] = val; - if (val != 0xFF) { - buslogic_log("BusLogic IRQ now: %i\n", val); - dev->Irq = val; - } else - dev->Irq = 0; - return; + case 0x3C: + buslogic_pci_regs[addr] = val; + if (val != 0xFF) { + buslogic_log("BusLogic IRQ now: %i\n", val); + dev->Irq = val; + } else + dev->Irq = 0; + return; } } - static void BuslogicInitializeLocalRAM(buslogic_data_t *bl) { memset(bl->LocalRAM.u8View, 0, sizeof(HALocalRAM)); if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; + bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; } else { - bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 0; + bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 0; } - bl->LocalRAM.structured.autoSCSIData.u16DeviceEnabledMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16WidePermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16FastPermittedMask = ~0; + bl->LocalRAM.structured.autoSCSIData.u16DeviceEnabledMask = ~0; + bl->LocalRAM.structured.autoSCSIData.u16WidePermittedMask = ~0; + bl->LocalRAM.structured.autoSCSIData.u16FastPermittedMask = ~0; bl->LocalRAM.structured.autoSCSIData.u16SynchronousPermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.u16DisconnectPermittedMask = ~0; - bl->LocalRAM.structured.autoSCSIData.fRoundRobinScheme = 0; - bl->LocalRAM.structured.autoSCSIData.u16UltraPermittedMask = ~0; + bl->LocalRAM.structured.autoSCSIData.u16DisconnectPermittedMask = ~0; + bl->LocalRAM.structured.autoSCSIData.fRoundRobinScheme = 0; + bl->LocalRAM.structured.autoSCSIData.u16UltraPermittedMask = ~0; } - static uint8_t buslogic_mca_read(int port, void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; - return(dev->pos_regs[port & 7]); + return (dev->pos_regs[port & 7]); } - static void buslogic_mca_write(int port, uint8_t val, void *priv) { - x54x_t *dev = (x54x_t *) priv; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; HALocalRAM *HALR = &bl->LocalRAM; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; /* Save the MCA register value. */ dev->pos_regs[port & 7] = val; @@ -1382,52 +1341,54 @@ buslogic_mca_write(int port, uint8_t val, void *priv) /* Get the new assigned I/O base address. */ if (dev->pos_regs[3]) { - dev->Base = dev->pos_regs[3] << 8; - dev->Base |= ((dev->pos_regs[2] & 0x10) ? 0x34 : 0x30); + dev->Base = dev->pos_regs[3] << 8; + dev->Base |= ((dev->pos_regs[2] & 0x10) ? 0x34 : 0x30); } else { - dev->Base = 0x0000; + dev->Base = 0x0000; } /* Save the new IRQ and DMA channel values. */ - dev->Irq = ((dev->pos_regs[2] >> 1) & 0x07) + 8; + dev->Irq = ((dev->pos_regs[2] >> 1) & 0x07) + 8; dev->DmaChannel = dev->pos_regs[5] & 0x0f; /* Extract the BIOS ROM address info. */ - if (dev->pos_regs[2] & 0xe0) switch(dev->pos_regs[2] & 0xe0) { - case 0xe0: /* [0]=111x xxxx */ - bl->bios_addr = 0xDC000; - break; + if (dev->pos_regs[2] & 0xe0) + switch (dev->pos_regs[2] & 0xe0) { + case 0xe0: /* [0]=111x xxxx */ + bl->bios_addr = 0xDC000; + break; - case 0x00: /* [0]=000x xxxx */ - bl->bios_addr = 0; - break; + case 0x00: /* [0]=000x xxxx */ + bl->bios_addr = 0; + break; - case 0xc0: /* [0]=110x xxxx */ - bl->bios_addr = 0xD8000; - break; + case 0xc0: /* [0]=110x xxxx */ + bl->bios_addr = 0xD8000; + break; - case 0xa0: /* [0]=101x xxxx */ - bl->bios_addr = 0xD4000; - break; + case 0xa0: /* [0]=101x xxxx */ + bl->bios_addr = 0xD4000; + break; - case 0x80: /* [0]=100x xxxx */ - bl->bios_addr = 0xD0000; - break; + case 0x80: /* [0]=100x xxxx */ + bl->bios_addr = 0xD0000; + break; - case 0x60: /* [0]=011x xxxx */ - bl->bios_addr = 0xCC000; - break; + case 0x60: /* [0]=011x xxxx */ + bl->bios_addr = 0xCC000; + break; - case 0x40: /* [0]=010x xxxx */ - bl->bios_addr = 0xC8000; - break; + case 0x40: /* [0]=010x xxxx */ + bl->bios_addr = 0xC8000; + break; - case 0x20: /* [0]=001x xxxx */ - bl->bios_addr = 0xC4000; - break; - } else { - /* Disabled. */ - bl->bios_addr = 0x000000; + case 0x20: /* [0]=001x xxxx */ + bl->bios_addr = 0xC4000; + break; + } + else { + /* Disabled. */ + bl->bios_addr = 0x000000; } /* @@ -1437,7 +1398,7 @@ buslogic_mca_write(int port, uint8_t val, void *priv) * pos[2]=111xxxxx = 7 * pos[2]=000xxxxx = 0 */ - dev->HostID = (dev->pos_regs[4] >> 5) & 0x07; + dev->HostID = (dev->pos_regs[4] >> 5) & 0x07; HALR->structured.autoSCSIData.uSCSIId = dev->HostID; /* @@ -1458,43 +1419,43 @@ buslogic_mca_write(int port, uint8_t val, void *priv) HALR->structured.autoSCSIData.uBIOSConfiguration &= ~4; HALR->structured.autoSCSIData.uBIOSConfiguration |= (dev->pos_regs[4] & 8) ? 4 : 0; - switch(dev->DmaChannel) { - case 5: - HALR->structured.autoSCSIData.uDMAChannel = 1; - break; - case 6: - HALR->structured.autoSCSIData.uDMAChannel = 2; - break; - case 7: - HALR->structured.autoSCSIData.uDMAChannel = 3; - break; - default: - HALR->structured.autoSCSIData.uDMAChannel = 0; - break; + switch (dev->DmaChannel) { + case 5: + HALR->structured.autoSCSIData.uDMAChannel = 1; + break; + case 6: + HALR->structured.autoSCSIData.uDMAChannel = 2; + break; + case 7: + HALR->structured.autoSCSIData.uDMAChannel = 3; + break; + default: + HALR->structured.autoSCSIData.uDMAChannel = 0; + break; } - switch(dev->Irq) { - case 9: - HALR->structured.autoSCSIData.uIrqChannel = 1; - break; - case 10: - HALR->structured.autoSCSIData.uIrqChannel = 2; - break; - case 11: - HALR->structured.autoSCSIData.uIrqChannel = 3; - break; - case 12: - HALR->structured.autoSCSIData.uIrqChannel = 4; - break; - case 14: - HALR->structured.autoSCSIData.uIrqChannel = 5; - break; - case 15: - HALR->structured.autoSCSIData.uIrqChannel = 6; - break; - default: - HALR->structured.autoSCSIData.uIrqChannel = 0; - break; + switch (dev->Irq) { + case 9: + HALR->structured.autoSCSIData.uIrqChannel = 1; + break; + case 10: + HALR->structured.autoSCSIData.uIrqChannel = 2; + break; + case 11: + HALR->structured.autoSCSIData.uIrqChannel = 3; + break; + case 12: + HALR->structured.autoSCSIData.uIrqChannel = 4; + break; + case 14: + HALR->structured.autoSCSIData.uIrqChannel = 5; + break; + case 15: + HALR->structured.autoSCSIData.uIrqChannel = 6; + break; + default: + HALR->structured.autoSCSIData.uIrqChannel = 0; + break; } /* @@ -1508,39 +1469,37 @@ buslogic_mca_write(int port, uint8_t val, void *priv) /* Initialize the device if fully configured. */ if (dev->pos_regs[2] & 0x01) { - /* Card enabled; register (new) I/O handler. */ - x54x_io_set(dev, dev->Base, 4); + /* Card enabled; register (new) I/O handler. */ + x54x_io_set(dev, dev->Base, 4); - /* Reset the device. */ - x54x_reset_ctrl(dev, CTRL_HRST); + /* Reset the device. */ + x54x_reset_ctrl(dev, CTRL_HRST); - /* Enable or disable the BIOS ROM. */ - if (bl->has_bios && (bl->bios_addr != 0x000000)) { - mem_mapping_enable(&bl->bios.mapping); - mem_mapping_set_addr(&bl->bios.mapping, bl->bios_addr, ROM_SIZE); - } + /* Enable or disable the BIOS ROM. */ + if (bl->has_bios && (bl->bios_addr != 0x000000)) { + mem_mapping_enable(&bl->bios.mapping); + mem_mapping_set_addr(&bl->bios.mapping, bl->bios_addr, ROM_SIZE); + } - /* Say hello. */ - buslogic_log("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", - dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID); + /* Say hello. */ + buslogic_log("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", + dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID); } } - static uint8_t buslogic_mca_feedb(void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; return (dev->pos_regs[2] & 0x01); } - void BuslogicDeviceReset(void *p) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) p; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; x54x_device_reset(dev); @@ -1548,26 +1507,25 @@ BuslogicDeviceReset(void *p) BuslogicInitializeAutoSCSIRam(dev); } - static void * buslogic_init(const device_t *info) { - x54x_t *dev; - char *bios_rom_name; - uint16_t bios_rom_size; - uint16_t bios_rom_mask; - uint8_t has_autoscsi_rom; - char *autoscsi_rom_name; - uint16_t autoscsi_rom_size; - uint8_t has_scam_rom; - char *scam_rom_name; - uint16_t scam_rom_size; - FILE *f; + x54x_t *dev; + char *bios_rom_name; + uint16_t bios_rom_size; + uint16_t bios_rom_mask; + uint8_t has_autoscsi_rom; + char *autoscsi_rom_name; + uint16_t autoscsi_rom_size; + uint8_t has_scam_rom; + char *scam_rom_name; + uint16_t scam_rom_size; + FILE *f; buslogic_data_t *bl; - uint32_t bios_rom_addr; + uint32_t bios_rom_addr; /* Call common initializer. */ - dev = x54x_init(info); + dev = x54x_init(info); dev->bus = scsi_get_bus(); dev->ven_data = malloc(sizeof(buslogic_data_t)); @@ -1577,229 +1535,225 @@ buslogic_init(const device_t *info) dev->card_bus = info->flags; if (!(info->flags & DEVICE_MCA) && !(info->flags & DEVICE_PCI)) { - dev->Base = device_get_config_hex16("base"); - dev->Irq = device_get_config_int("irq"); - dev->DmaChannel = device_get_config_int("dma"); + dev->Base = device_get_config_hex16("base"); + dev->Irq = device_get_config_int("irq"); + dev->DmaChannel = device_get_config_int("dma"); + } else if (info->flags & DEVICE_PCI) { + dev->Base = 0; } - else if (info->flags & DEVICE_PCI) { - dev->Base = 0; - } - dev->HostID = 7; /* default HA ID */ + dev->HostID = 7; /* default HA ID */ dev->setup_info_len = sizeof(buslogic_setup_t); - dev->max_id = 7; - dev->flags = X54X_INT_GEOM_WRITABLE; + dev->max_id = 7; + dev->flags = X54X_INT_GEOM_WRITABLE; - bl->chip = info->local; - bl->PCIBase = 0; + bl->chip = info->local; + bl->PCIBase = 0; bl->MMIOBase = 0; if (info->flags & DEVICE_PCI) { - bios_rom_addr = 0xd8000; - bl->has_bios = device_get_config_int("bios"); + bios_rom_addr = 0xd8000; + bl->has_bios = device_get_config_int("bios"); } else if (info->flags & DEVICE_MCA) { - bios_rom_addr = 0xd8000; - bl->has_bios = 1; + bios_rom_addr = 0xd8000; + bl->has_bios = 1; } else { - bios_rom_addr = device_get_config_hex20("bios_addr"); - bl->has_bios = !!bios_rom_addr; + bios_rom_addr = device_get_config_hex20("bios_addr"); + bl->has_bios = !!bios_rom_addr; } - dev->ven_cmd_phase1 = buslogic_cmd_phase1; - dev->ven_get_host_id = buslogic_get_host_id; - dev->ven_get_irq = buslogic_get_irq; - dev->ven_get_dma = buslogic_get_dma; - dev->get_ven_param_len = buslogic_param_len; - dev->ven_cmds = buslogic_cmds; - dev->interrupt_type = buslogic_interrupt_type; + dev->ven_cmd_phase1 = buslogic_cmd_phase1; + dev->ven_get_host_id = buslogic_get_host_id; + dev->ven_get_irq = buslogic_get_irq; + dev->ven_get_dma = buslogic_get_dma; + dev->get_ven_param_len = buslogic_param_len; + dev->ven_cmds = buslogic_cmds; + dev->interrupt_type = buslogic_interrupt_type; dev->is_aggressive_mode = buslogic_is_aggressive_mode; - dev->get_ven_data = buslogic_setup_data; - dev->ven_reset = buslogic_reset; + dev->get_ven_data = buslogic_setup_data; + dev->ven_reset = buslogic_reset; strcpy(dev->vendor, "BusLogic"); bl->fAggressiveRoundRobinMode = 1; - bios_rom_name = NULL; - has_autoscsi_rom = 0; - has_scam_rom = 0; + bios_rom_name = NULL; + has_autoscsi_rom = 0; + has_scam_rom = 0; - switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542B_1991_12_14: /*Dated December 14th, 1991*/ - strcpy(dev->name, "BT-542B"); - bios_rom_name = "roms/scsi/buslogic/BT-542B_BIOS.ROM"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA221"; - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_ISA_545S_1992_10_05: /*Dated October 5th, 1992*/ - strcpy(dev->name, "BT-545S"); - bios_rom_name = "roms/scsi/buslogic/BT-545S_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA331"; - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: /*Dated May 23rd, 1993*/ - strcpy(dev->name, "BT-542BH"); - bios_rom_name = "roms/scsi/buslogic/BT-542BH_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA335"; - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_ISA_545C_1994_12_01: /*Dated December 1st, 1994*/ - strcpy(dev->name, "BT-545C"); - bios_rom_name = "roms/scsi/buslogic/BT-545C_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = "roms/scsi/buslogic/BT-545C_AutoSCSI.rom"; - autoscsi_rom_size = 0x4000; - has_scam_rom = 0; - dev->fw_rev = "AA425J"; - dev->ha_bps = 10000000.0; /* fast SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_MCA_640A_1993_05_23: /*Dated May 23rd, 1993*/ - strcpy(dev->name, "BT-640A"); - bios_rom_name = "roms/scsi/buslogic/BT-640A_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "BA335"; - dev->flags |= X54X_32BIT; - dev->pos_regs[0] = 0x08; /* MCA board ID */ - dev->pos_regs[1] = 0x07; - mca_add(buslogic_mca_read, buslogic_mca_write, buslogic_mca_feedb, NULL, dev); - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_VLB_445S_1993_11_16: /*Dated November 16th, 1993*/ - strcpy(dev->name, "BT-445S"); - bios_rom_name = "roms/scsi/buslogic/BT-445S_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA335"; - dev->flags |= X54X_32BIT; - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_VLB_445C_1994_12_01: /*Dated December 1st, 1994*/ - strcpy(dev->name, "BT-445C"); - bios_rom_name = "roms/scsi/buslogic/BT-445C_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = "roms/scsi/buslogic/BT-445C_AutoSCSI.rom"; - autoscsi_rom_size = 0x4000; - has_scam_rom = 0; - dev->fw_rev = "AA425J"; - dev->flags |= X54X_32BIT; - dev->ha_bps = 10000000.0; /* fast SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_PCI_958D_1995_12_30: /*Dated December 30th, 1995*/ - strcpy(dev->name, "BT-958D"); - bios_rom_name = "roms/scsi/buslogic/BT-958D_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = "roms/scsi/buslogic/BT-958D_AutoSCSI.rom"; - autoscsi_rom_size = 0x8000; - has_scam_rom = 1; - scam_rom_name = "roms/scsi/buslogic/BT-958D_SCAM.rom"; - scam_rom_size = 0x0200; - dev->fw_rev = "AA507B"; - dev->flags |= (X54X_CDROM_BOOT | X54X_32BIT); - dev->ha_bps = 20000000.0; /* ultra SCSI */ - dev->max_id = 15; /* wide SCSI */ - break; - } + switch (bl->chip) { + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: /*Dated December 14th, 1991*/ + strcpy(dev->name, "BT-542B"); + bios_rom_name = "roms/scsi/buslogic/BT-542B_BIOS.ROM"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA221"; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: /*Dated October 5th, 1992*/ + strcpy(dev->name, "BT-545S"); + bios_rom_name = "roms/scsi/buslogic/BT-545S_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA331"; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: /*Dated May 23rd, 1993*/ + strcpy(dev->name, "BT-542BH"); + bios_rom_name = "roms/scsi/buslogic/BT-542BH_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA335"; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: /*Dated December 1st, 1994*/ + strcpy(dev->name, "BT-545C"); + bios_rom_name = "roms/scsi/buslogic/BT-545C_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 1; + autoscsi_rom_name = "roms/scsi/buslogic/BT-545C_AutoSCSI.rom"; + autoscsi_rom_size = 0x4000; + has_scam_rom = 0; + dev->fw_rev = "AA425J"; + dev->ha_bps = 10000000.0; /* fast SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: /*Dated May 23rd, 1993*/ + strcpy(dev->name, "BT-640A"); + bios_rom_name = "roms/scsi/buslogic/BT-640A_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "BA335"; + dev->flags |= X54X_32BIT; + dev->pos_regs[0] = 0x08; /* MCA board ID */ + dev->pos_regs[1] = 0x07; + mca_add(buslogic_mca_read, buslogic_mca_write, buslogic_mca_feedb, NULL, dev); + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: /*Dated November 16th, 1993*/ + strcpy(dev->name, "BT-445S"); + bios_rom_name = "roms/scsi/buslogic/BT-445S_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA335"; + dev->flags |= X54X_32BIT; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: /*Dated December 1st, 1994*/ + strcpy(dev->name, "BT-445C"); + bios_rom_name = "roms/scsi/buslogic/BT-445C_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 1; + autoscsi_rom_name = "roms/scsi/buslogic/BT-445C_AutoSCSI.rom"; + autoscsi_rom_size = 0x4000; + has_scam_rom = 0; + dev->fw_rev = "AA425J"; + dev->flags |= X54X_32BIT; + dev->ha_bps = 10000000.0; /* fast SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: /*Dated December 30th, 1995*/ + strcpy(dev->name, "BT-958D"); + bios_rom_name = "roms/scsi/buslogic/BT-958D_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 1; + autoscsi_rom_name = "roms/scsi/buslogic/BT-958D_AutoSCSI.rom"; + autoscsi_rom_size = 0x8000; + has_scam_rom = 1; + scam_rom_name = "roms/scsi/buslogic/BT-958D_SCAM.rom"; + scam_rom_size = 0x0200; + dev->fw_rev = "AA507B"; + dev->flags |= (X54X_CDROM_BOOT | X54X_32BIT); + dev->ha_bps = 20000000.0; /* ultra SCSI */ + dev->max_id = 15; /* wide SCSI */ + break; + } if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) { - x54x_io_set(dev, dev->Base, 4); + x54x_io_set(dev, dev->Base, 4); } memset(bl->AutoSCSIROM, 0xff, 32768); memset(bl->SCAMData, 0x00, 65536); - if (bl->has_bios) - { - bl->bios_size = bios_rom_size; + if (bl->has_bios) { + bl->bios_size = bios_rom_size; - bl->bios_mask = 0xffffc000; + bl->bios_mask = 0xffffc000; - rom_init(&bl->bios, bios_rom_name, bios_rom_addr, bios_rom_size, bios_rom_mask, 0, MEM_MAPPING_EXTERNAL); + rom_init(&bl->bios, bios_rom_name, bios_rom_addr, bios_rom_size, bios_rom_mask, 0, MEM_MAPPING_EXTERNAL); - if (has_autoscsi_rom) { - f = rom_fopen(autoscsi_rom_name, "rb"); - if (f) { - (void) !fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, f); - fclose(f); - f = NULL; - } - } + if (has_autoscsi_rom) { + f = rom_fopen(autoscsi_rom_name, "rb"); + if (f) { + (void) !fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, f); + fclose(f); + f = NULL; + } + } - if (has_scam_rom) { - f = rom_fopen(scam_rom_name, "rb"); - if (f) { - (void) !fread(bl->SCAMData, 1, scam_rom_size, f); - fclose(f); - f = NULL; - } - } - } - else { - bl->bios_size = 0; + if (has_scam_rom) { + f = rom_fopen(scam_rom_name, "rb"); + if (f) { + (void) !fread(bl->SCAMData, 1, scam_rom_size, f); + fclose(f); + f = NULL; + } + } + } else { + bl->bios_size = 0; - bl->bios_mask = 0; + bl->bios_mask = 0; } if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev); + dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev); - buslogic_pci_bar[0].addr_regs[0] = 1; - buslogic_pci_bar[1].addr_regs[0] = 0; - buslogic_pci_regs[0x04] = 3; + buslogic_pci_bar[0].addr_regs[0] = 1; + buslogic_pci_bar[1].addr_regs[0] = 0; + buslogic_pci_regs[0x04] = 3; - /* Enable our BIOS space in PCI, if needed. */ - if (bl->has_bios) { - buslogic_pci_bar[2].addr = 0xFFFFC000; - } else { - buslogic_pci_bar[2].addr = 0; - } + /* Enable our BIOS space in PCI, if needed. */ + if (bl->has_bios) { + buslogic_pci_bar[2].addr = 0xFFFFC000; + } else { + buslogic_pci_bar[2].addr = 0; + } - x54x_mem_init(dev, 0xfffd0000); - x54x_mem_disable(dev); + x54x_mem_init(dev, 0xfffd0000); + x54x_mem_disable(dev); } if ((bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30)) - mem_mapping_disable(&bl->bios.mapping); + mem_mapping_disable(&bl->bios.mapping); buslogic_log("Buslogic on port 0x%04X\n", dev->Base); x54x_device_reset(dev); - if ((bl->chip != CHIP_BUSLOGIC_ISA_542B_1991_12_14) && (bl->chip != CHIP_BUSLOGIC_ISA_545S_1992_10_05) && (bl->chip != CHIP_BUSLOGIC_ISA_542BH_1993_05_23) && - (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16) && (bl->chip != CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { - BuslogicInitializeLocalRAM(bl); - BuslogicInitializeAutoSCSIRam(dev); + if ((bl->chip != CHIP_BUSLOGIC_ISA_542B_1991_12_14) && (bl->chip != CHIP_BUSLOGIC_ISA_545S_1992_10_05) && (bl->chip != CHIP_BUSLOGIC_ISA_542BH_1993_05_23) && (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16) && (bl->chip != CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { + BuslogicInitializeLocalRAM(bl); + BuslogicInitializeAutoSCSIRam(dev); } - return(dev); + return (dev); } // clang-format off @@ -1887,113 +1841,113 @@ static const device_config_t BT958D_Config[] = { // clang-format on const device_t buslogic_542b_device = { - .name = "BusLogic BT-542B ISA", + .name = "BusLogic BT-542B ISA", .internal_name = "bt542b", - .flags = DEVICE_ISA | DEVICE_AT, - .local = CHIP_BUSLOGIC_ISA_542B_1991_12_14, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = CHIP_BUSLOGIC_ISA_542B_1991_12_14, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT_ISA_Config + .force_redraw = NULL, + .config = BT_ISA_Config }; const device_t buslogic_545s_device = { - .name = "BusLogic BT-545S ISA", + .name = "BusLogic BT-545S ISA", .internal_name = "bt545s", - .flags = DEVICE_ISA | DEVICE_AT, - .local = CHIP_BUSLOGIC_ISA_545S_1992_10_05, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = CHIP_BUSLOGIC_ISA_545S_1992_10_05, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT_ISA_Config + .force_redraw = NULL, + .config = BT_ISA_Config }; const device_t buslogic_542bh_device = { - .name = "BusLogic BT-542BH ISA", + .name = "BusLogic BT-542BH ISA", .internal_name = "bt542bh", - .flags = DEVICE_ISA | DEVICE_AT, - .local = CHIP_BUSLOGIC_ISA_542BH_1993_05_23, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = CHIP_BUSLOGIC_ISA_542BH_1993_05_23, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT_ISA_Config + .force_redraw = NULL, + .config = BT_ISA_Config }; const device_t buslogic_545c_device = { - .name = "BusLogic BT-545C ISA", + .name = "BusLogic BT-545C ISA", .internal_name = "bt545c", - .flags = DEVICE_ISA | DEVICE_AT, - .local = CHIP_BUSLOGIC_ISA_545C_1994_12_01, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = CHIP_BUSLOGIC_ISA_545C_1994_12_01, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT_ISA_Config + .force_redraw = NULL, + .config = BT_ISA_Config }; const device_t buslogic_640a_device = { - .name = "BusLogic BT-640A MCA", + .name = "BusLogic BT-640A MCA", .internal_name = "bt640a", - .flags = DEVICE_MCA, - .local = CHIP_BUSLOGIC_MCA_640A_1993_05_23, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = CHIP_BUSLOGIC_MCA_640A_1993_05_23, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t buslogic_445s_device = { - .name = "BusLogic BT-445S VLB", + .name = "BusLogic BT-445S VLB", .internal_name = "bt445s", - .flags = DEVICE_VLB, - .local = CHIP_BUSLOGIC_VLB_445S_1993_11_16, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = CHIP_BUSLOGIC_VLB_445S_1993_11_16, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT_ISA_Config + .force_redraw = NULL, + .config = BT_ISA_Config }; const device_t buslogic_445c_device = { - .name = "BusLogic BT-445C VLB", + .name = "BusLogic BT-445C VLB", .internal_name = "bt445c", - .flags = DEVICE_VLB, - .local = CHIP_BUSLOGIC_VLB_445C_1994_12_01, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = CHIP_BUSLOGIC_VLB_445C_1994_12_01, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT_ISA_Config + .force_redraw = NULL, + .config = BT_ISA_Config }; const device_t buslogic_958d_pci_device = { - .name = "BusLogic BT-958D PCI", + .name = "BusLogic BT-958D PCI", .internal_name = "bt958d", - .flags = DEVICE_PCI, - .local = CHIP_BUSLOGIC_PCI_958D_1995_12_30, - .init = buslogic_init, - .close = x54x_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_BUSLOGIC_PCI_958D_1995_12_30, + .init = buslogic_init, + .close = x54x_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = BT958D_Config + .force_redraw = NULL, + .config = BT958D_Config }; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index e90e0d773..033a2bf42 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -39,317 +39,300 @@ #include <86box/scsi_cdrom.h> #include <86box/version.h> - -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t opcode; - uint8_t polled; - uint8_t reserved2[2]; - uint8_t class; - uint8_t reserved3[2]; - uint16_t len; - uint8_t control; + uint8_t opcode; + uint8_t polled; + uint8_t reserved2[2]; + uint8_t class; + uint8_t reserved3[2]; + uint16_t len; + uint8_t control; } gesn_cdb_t; typedef struct { - uint16_t len; - uint8_t notification_class; - uint8_t supported_events; + uint16_t len; + uint8_t notification_class; + uint8_t supported_events; } gesn_event_header_t; #pragma pack(pop) - /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t scsi_cdrom_command_flags[0x100] = -{ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, /* 0x02 */ - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, /* 0x04-0x07 */ - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, 0, /* 0x09-0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, /* 0x14 */ - IMPLEMENTED, /* 0x15 */ - 0, 0, 0, 0, /* 0x16-0x19 */ - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, 0, /* 0x1C-0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, /* 0x26-0x27 */ - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, 0, /* 0x29-0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, 0, /* 0x2C-0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ - 0, 0, /* 0x40-0x41 */ - IMPLEMENTED | CHECK_READY, /* 0x42 */ - IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - IMPLEMENTED | CHECK_READY, /* 0x44 */ - IMPLEMENTED | CHECK_READY, /* 0x45 */ - IMPLEMENTED | ALLOW_UA, /* 0x46 */ - IMPLEMENTED | CHECK_READY, /* 0x47 */ - IMPLEMENTED | CHECK_READY, /* 0x48 */ - IMPLEMENTED | CHECK_READY, /* 0x49 */ - IMPLEMENTED | ALLOW_UA, /* 0x4A */ - IMPLEMENTED | CHECK_READY, /* 0x4B */ - 0, 0, /* 0x4C-0x4D */ - IMPLEMENTED | CHECK_READY, /* 0x4E */ - 0, 0, /* 0x4F-0x50 */ - IMPLEMENTED | CHECK_READY, /* 0x51 */ - IMPLEMENTED | CHECK_READY, /* 0x52 */ - 0, 0, /* 0x53-0x54 */ - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, /* 0x56-0x59 */ - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, /* 0x5B-0x5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ - 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ - IMPLEMENTED | CHECK_READY, /* 0xA5 */ - 0, 0, /* 0xA6-0xA7 */ - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - IMPLEMENTED | CHECK_READY, /* 0xA9 */ - 0, 0, 0, /* 0xAA-0xAC */ - IMPLEMENTED | CHECK_READY, /* 0xAD */ - 0, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, /* 0xB0-0xB3 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ - 0, 0, 0, /* 0xB5-0xB7 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ - IMPLEMENTED | CHECK_READY, /* 0xB9 */ - IMPLEMENTED | CHECK_READY, /* 0xBA */ - IMPLEMENTED, /* 0xBB */ - IMPLEMENTED | CHECK_READY, /* 0xBC */ - IMPLEMENTED, /* 0xBD */ - IMPLEMENTED | CHECK_READY, /* 0xBE */ - IMPLEMENTED | CHECK_READY, /* 0xBF */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ - 0, /* 0xC3 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ - 0, /* 0xC5 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ - 0, 0, 0, 0, 0, /* 0xC8-0xCC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ - IMPLEMENTED | SCSI_ONLY, /* 0xDA */ - 0, 0, 0, 0, 0, /* 0xDB-0xDF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ +const uint8_t scsi_cdrom_command_flags[0x100] = { + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ + 0, /* 0x02 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + 0, 0, 0, 0, /* 0x04-0x07 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ + 0, 0, /* 0x09-0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + 0, /* 0x14 */ + IMPLEMENTED, /* 0x15 */ + 0, 0, 0, 0, /* 0x16-0x19 */ + IMPLEMENTED, /* 0x1A */ + IMPLEMENTED | CHECK_READY, /* 0x1B */ + 0, 0, /* 0x1C-0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ + 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ + 0, 0, /* 0x26-0x27 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ + 0, 0, /* 0x29-0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + 0, 0, 0, /* 0x2C-0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ + 0, 0, /* 0x40-0x41 */ + IMPLEMENTED | CHECK_READY, /* 0x42 */ + IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + NOTE: The ATAPI reference says otherwise, but I think this is a question of + interpreting things right - the UNIT ATTENTION condition we have here + is a tradition from not ready to ready, by definition the drive + eventually becomes ready, make the condition go away. */ + IMPLEMENTED | CHECK_READY, /* 0x44 */ + IMPLEMENTED | CHECK_READY, /* 0x45 */ + IMPLEMENTED | ALLOW_UA, /* 0x46 */ + IMPLEMENTED | CHECK_READY, /* 0x47 */ + IMPLEMENTED | CHECK_READY, /* 0x48 */ + IMPLEMENTED | CHECK_READY, /* 0x49 */ + IMPLEMENTED | ALLOW_UA, /* 0x4A */ + IMPLEMENTED | CHECK_READY, /* 0x4B */ + 0, 0, /* 0x4C-0x4D */ + IMPLEMENTED | CHECK_READY, /* 0x4E */ + 0, 0, /* 0x4F-0x50 */ + IMPLEMENTED | CHECK_READY, /* 0x51 */ + IMPLEMENTED | CHECK_READY, /* 0x52 */ + 0, 0, /* 0x53-0x54 */ + IMPLEMENTED, /* 0x55 */ + 0, 0, 0, 0, /* 0x56-0x59 */ + IMPLEMENTED, /* 0x5A */ + 0, 0, 0, 0, 0, /* 0x5B-0x5F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ + 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ + IMPLEMENTED | CHECK_READY, /* 0xA5 */ + 0, 0, /* 0xA6-0xA7 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ + IMPLEMENTED | CHECK_READY, /* 0xA9 */ + 0, 0, 0, /* 0xAA-0xAC */ + IMPLEMENTED | CHECK_READY, /* 0xAD */ + 0, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + 0, 0, 0, 0, /* 0xB0-0xB3 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ + 0, 0, 0, /* 0xB5-0xB7 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ + IMPLEMENTED | CHECK_READY, /* 0xB9 */ + IMPLEMENTED | CHECK_READY, /* 0xBA */ + IMPLEMENTED, /* 0xBB */ + IMPLEMENTED | CHECK_READY, /* 0xBC */ + IMPLEMENTED, /* 0xBD */ + IMPLEMENTED | CHECK_READY, /* 0xBE */ + IMPLEMENTED | CHECK_READY, /* 0xBF */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ + 0, /* 0xC3 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ + 0, /* 0xC5 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ + 0, 0, 0, 0, 0, /* 0xC8-0xCC */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ + IMPLEMENTED | SCSI_ONLY, /* 0xDA */ + 0, 0, 0, 0, 0, /* 0xDB-0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ }; -static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | - GPMODEP_DISCONNECT_PAGE | - GPMODEP_CDROM_PAGE | - GPMODEP_CDROM_AUDIO_PAGE | - (1ULL << 0x0fULL) | - GPMODEP_CAPABILITIES_PAGE | - GPMODEP_ALL_PAGES); +static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } -} }; +static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = { + {{ 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 }} +}; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { 0x8E, 0xE, 5, 4, 0,128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } -} }; +static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { + {{ 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 5, 4, 0, 128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 }} +}; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0x8E, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -} }; +static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { + {{ 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, + { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x8E, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} +}; -static gesn_cdb_t *gesn_cdb; +static gesn_cdb_t *gesn_cdb; static gesn_event_header_t *gesn_event_header; +static void scsi_cdrom_command_complete(scsi_cdrom_t *dev); -static void scsi_cdrom_command_complete(scsi_cdrom_t *dev); - -static void scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev); - -static void scsi_cdrom_init(scsi_cdrom_t *dev); +static void scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev); +static void scsi_cdrom_init(scsi_cdrom_t *dev); #ifdef ENABLE_SCSI_CDROM_LOG int scsi_cdrom_do_log = ENABLE_SCSI_CDROM_LOG; - static void scsi_cdrom_log(const char *format, ...) { va_list ap; if (scsi_cdrom_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); + va_start(ap, format); + pclog_ex(format, ap); + va_end(ap); } } #else -#define scsi_cdrom_log(format, ...) +# define scsi_cdrom_log(format, ...) #endif - static void scsi_cdrom_set_callback(scsi_cdrom_t *dev) { if (dev && dev->drv && (dev->drv->bus_type != CDROM_BUS_SCSI)) - ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } - static void scsi_cdrom_init(scsi_cdrom_t *dev) { if (!dev) - return; + return; /* Do a reset (which will also rezero it). */ scsi_cdrom_reset((scsi_common_t *) dev); @@ -359,206 +342,197 @@ scsi_cdrom_init(scsi_cdrom_t *dev) dev->drv->bus_mode = 0; if (dev->drv->bus_type >= CDROM_BUS_ATAPI) - dev->drv->bus_mode |= 2; + dev->drv->bus_mode |= 2; if (dev->drv->bus_type < CDROM_BUS_SCSI) - dev->drv->bus_mode |= 1; + dev->drv->bus_mode |= 1; scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; - dev->packet_status = PHASE_NONE; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + dev->status = READY_STAT | DSC_STAT; + dev->pos = 0; + dev->packet_status = PHASE_NONE; scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; - dev->drv->cur_speed = dev->drv->speed; + dev->drv->cur_speed = dev->drv->speed; scsi_cdrom_mode_sense_load(dev); } - /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int scsi_cdrom_current_mode(scsi_cdrom_t *dev) { if (dev->drv->bus_type == CDROM_BUS_SCSI) - return 2; + return 2; else if (dev->drv->bus_type == CDROM_BUS_ATAPI) { - scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id, - (dev->features & 1) ? "DMA" : "PIO", - dev->id); - return (dev->features & 1) ? 2 : 1; + scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id, + (dev->features & 1) ? "DMA" : "PIO", + dev->id); + return (dev->features & 1) ? 2 : 1; } return 0; } - /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ int scsi_cdrom_atapi_phase_to_scsi(scsi_cdrom_t *dev) { if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } + switch (dev->phase & 3) { + case 0: + return 0; + case 1: + return 2; + case 2: + return 1; + case 3: + return 7; + } } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + if ((dev->phase & 3) == 3) + return 3; + else + return 4; } return 0; } - static uint32_t scsi_cdrom_get_channel(void *p, int channel) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; if (!dev) - return channel + 1; + return channel + 1; return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; } - static uint32_t scsi_cdrom_get_volume(void *p, int channel) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; if (!dev) - return 255; + return 255; return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; } - static void scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (dev->drv->bus_type == CDROM_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); else - memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, sizeof(mode_sense_pages_t)); memset(file_name, 0, 512); if (dev->drv->bus_type == CDROM_BUS_SCSI) - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), "rb"); if (f) { - if (fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f) != 0x10) - fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); - fclose(f); + if (fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f) != 0x10) + fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); + fclose(f); } } - static void scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(file_name, 0, 512); if (dev->drv->bus_type == CDROM_BUS_SCSI) - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), "wb"); if (f) { - fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); - fclose(f); + fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); + fclose(f); } } - /*SCSI Mode Sense 6/10*/ static uint8_t scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - return scsi_cdrom_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (dev->drv->bus_type == CDROM_BUS_SCSI) - return scsi_cdrom_mode_sense_pages_default_scsi.pages[page][pos]; - else - return scsi_cdrom_mode_sense_pages_default.pages[page][pos]; - break; + case 0: + case 3: + return dev->ms_pages_saved.pages[page][pos]; + break; + case 1: + return scsi_cdrom_mode_sense_pages_changeable.pages[page][pos]; + break; + case 2: + if (dev->drv->bus_type == CDROM_BUS_SCSI) + return scsi_cdrom_mode_sense_pages_default_scsi.pages[page][pos]; + else + return scsi_cdrom_mode_sense_pages_default.pages[page][pos]; + break; } return 0; } - static uint32_t scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) { uint8_t page_control = (page >> 6) & 3; - int i = 0, j = 0; + int i = 0, j = 0; uint8_t msplen; page &= 0x3f; if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = 0; /* Number of blocks (0 = all). */ - buf[pos++] = 0; - buf[pos++] = 0; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x800 = 2048 bytes). */ - buf[pos++] = 8; - buf[pos++] = 0; + buf[pos++] = 1; /* Density code. */ + buf[pos++] = 0; /* Number of blocks (0 = all). */ + buf[pos++] = 0; + buf[pos++] = 0; + buf[pos++] = 0; /* Reserved. */ + buf[pos++] = 0; /* Block length (0x800 = 2048 bytes). */ + buf[pos++] = 8; + buf[pos++] = 0; } for (i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { - if (scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 0); - msplen = scsi_cdrom_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - scsi_cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) { - if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { - if (j & 1) - buf[pos++] = ((dev->drv->speed * 176) & 0xff); - else - buf[pos++] = ((dev->drv->speed * 176) >> 8); - } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { - if (j & 1) - buf[pos++] = ((dev->drv->cur_speed * 176) & 0xff); - else - buf[pos++] = ((dev->drv->cur_speed * 176) >> 8); - } else - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); - } - } - } + if (scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { + buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 0); + msplen = scsi_cdrom_mode_sense_read(dev, page_control, i, 1); + buf[pos++] = msplen; + scsi_cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + for (j = 0; j < msplen; j++) { + if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { + if (j & 1) + buf[pos++] = ((dev->drv->speed * 176) & 0xff); + else + buf[pos++] = ((dev->drv->speed * 176) >> 8); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { + if (j & 1) + buf[pos++] = ((dev->drv->cur_speed * 176) & 0xff); + else + buf[pos++] = ((dev->drv->cur_speed * 176) >> 8); + } else + buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); + } + } + } } return pos; } - static void scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) { @@ -568,146 +542,143 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { - case 0x08: - case 0x28: - case 0xa8: - /* Round it to the nearest 2048 bytes. */ - dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; - /* FALLTHROUGH */ + case 0x08: + case 0x28: + case 0xa8: + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; + /* FALLTHROUGH */ - case 0xb9: - case 0xbe: - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ - bt = (dev->requested_blocks * block_len); - if (len > bt) - len = bt; + case 0xb9: + case 0xbe: + /* Make sure total length is not bigger than sum of the lengths of + all the requested blocks. */ + bt = (dev->requested_blocks * block_len); + if (len > bt) + len = bt; - min_len = block_len; + min_len = block_len; - if (len <= block_len) { - /* Total length is less or equal to block length. */ - if (dev->max_transfer_len < block_len) { - /* Transfer a minimum of (block size) bytes. */ - dev->max_transfer_len = block_len; - dev->packet_len = block_len; - break; - } - } - /*FALLTHROUGH*/ - default: - dev->packet_len = len; - break; + if (len <= block_len) { + /* Total length is less or equal to block length. */ + if (dev->max_transfer_len < block_len) { + /* Transfer a minimum of (block size) bytes. */ + dev->max_transfer_len = block_len; + dev->packet_len = block_len; + break; + } + } + /*FALLTHROUGH*/ + default: + dev->packet_len = len; + break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) - dev->max_transfer_len &= 0xfffe; + dev->max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ if (!dev->max_transfer_len) - dev->max_transfer_len = 65534; + dev->max_transfer_len = 65534; if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; + dev->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; + dev->request_length = dev->max_transfer_len; return; } - static double scsi_cdrom_bus_speed(scsi_cdrom_t *dev) { double ret = -1.0; if (dev && dev->drv && (dev->drv->bus_type == CDROM_BUS_SCSI)) { - dev->callback = -1.0; /* Speed depends on SCSI controller */ - return 0.0; + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return 0.0; } else { - if (dev && dev->drv) - ret = ide_atapi_get_period(dev->drv->ide_channel); - if (ret == -1.0) { - if (dev) - dev->callback = -1.0; - return 0.0; - } else - return ret * 1000000.0; + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + if (dev) + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; } } - static void scsi_cdrom_command_common(scsi_cdrom_t *dev) { double bytes_per_second, period; - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; + dev->status = BUSY_STAT; + dev->phase = 1; + dev->pos = 0; dev->callback = 0; scsi_cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed); if (dev->packet_status == PHASE_COMPLETE) - dev->callback = 0; + dev->callback = 0; else { - switch(dev->current_cdb[0]) { - case GPCMD_REZERO_UNIT: - case 0x0b: - case 0x2b: - /* Seek time is in us. */ - period = cdrom_seek_time(dev->drv); - scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); - dev->callback += period; - scsi_cdrom_set_callback(dev); - return; - case 0x08: - case 0x28: - case 0xa8: - /* Seek time is in us. */ - period = cdrom_seek_time(dev->drv); - scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); - dev->callback += period; - /*FALLTHROUGH*/ - case 0x25: - case 0x42: - case 0x43: - case 0x44: - case 0x51: - case 0x52: - case 0xad: - case 0xb8: - case 0xb9: - case 0xbe: - case 0xc6: - case 0xc7: - if (dev->current_cdb[0] == 0x42) - dev->callback += 40.0; - /* Account for seek time. */ - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->drv->cur_speed; - break; - default: - bytes_per_second = scsi_cdrom_bus_speed(dev); - if (bytes_per_second == 0.0) { - dev->callback = -1; /* Speed depends on SCSI controller */ - return; - } - break; - } + switch (dev->current_cdb[0]) { + case GPCMD_REZERO_UNIT: + case 0x0b: + case 0x2b: + /* Seek time is in us. */ + period = cdrom_seek_time(dev->drv); + scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", + dev->id, (uint64_t) period); + dev->callback += period; + scsi_cdrom_set_callback(dev); + return; + case 0x08: + case 0x28: + case 0xa8: + /* Seek time is in us. */ + period = cdrom_seek_time(dev->drv); + scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", + dev->id, (uint64_t) period); + dev->callback += period; + /*FALLTHROUGH*/ + case 0x25: + case 0x42: + case 0x43: + case 0x44: + case 0x51: + case 0x52: + case 0xad: + case 0xb8: + case 0xb9: + case 0xbe: + case 0xc6: + case 0xc7: + if (dev->current_cdb[0] == 0x42) + dev->callback += 40.0; + /* Account for seek time. */ + bytes_per_second = 176.0 * 1024.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; + default: + bytes_per_second = scsi_cdrom_bus_speed(dev); + if (bytes_per_second == 0.0) { + dev->callback = -1; /* Speed depends on SCSI controller */ + return; + } + break; + } - period = 1000000.0 / bytes_per_second; - scsi_cdrom_log("CD-ROM %i: Byte transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); - period = period * (double) (dev->packet_len); - scsi_cdrom_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); - dev->callback += period; + period = 1000000.0 / bytes_per_second; + scsi_cdrom_log("CD-ROM %i: Byte transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + period = period * (double) (dev->packet_len); + scsi_cdrom_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + dev->callback += period; } scsi_cdrom_set_callback(dev); } - static void scsi_cdrom_command_complete(scsi_cdrom_t *dev) { @@ -716,7 +687,6 @@ scsi_cdrom_command_complete(scsi_cdrom_t *dev) scsi_cdrom_command_common(dev); } - static void scsi_cdrom_command_read(scsi_cdrom_t *dev) { @@ -724,7 +694,6 @@ scsi_cdrom_command_read(scsi_cdrom_t *dev) scsi_cdrom_command_common(dev); } - static void scsi_cdrom_command_read_dma(scsi_cdrom_t *dev) { @@ -732,7 +701,6 @@ scsi_cdrom_command_read_dma(scsi_cdrom_t *dev) scsi_cdrom_command_common(dev); } - static void scsi_cdrom_command_write(scsi_cdrom_t *dev) { @@ -740,132 +708,125 @@ scsi_cdrom_command_write(scsi_cdrom_t *dev) scsi_cdrom_command_common(dev); } - -static void scsi_cdrom_command_write_dma(scsi_cdrom_t *dev) +static void +scsi_cdrom_command_write_dma(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_OUT_DMA; scsi_cdrom_command_common(dev); } - /* id = Current CD-ROM device ID; len = Total transfer length; block_len = Length of a single block (it matters because media access commands on ATAPI); alloc_len = Allocated transfer length; direction = Transfer direction (0 = read from host, 1 = write to host). */ -static void scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction) +static void +scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction) { scsi_cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); dev->pos = 0; if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; + if (alloc_len < len) + len = alloc_len; } if ((len == 0) || (scsi_cdrom_current_mode(dev) == 0)) { - if (dev->drv->bus_type != CDROM_BUS_SCSI) - dev->packet_len = 0; + if (dev->drv->bus_type != CDROM_BUS_SCSI) + dev->packet_len = 0; - scsi_cdrom_command_complete(dev); + scsi_cdrom_command_complete(dev); } else { - if (scsi_cdrom_current_mode(dev) == 2) { - if (dev->drv->bus_type != CDROM_BUS_SCSI) - dev->packet_len = alloc_len; + if (scsi_cdrom_current_mode(dev) == 2) { + if (dev->drv->bus_type != CDROM_BUS_SCSI) + dev->packet_len = alloc_len; - if (direction == 0) - scsi_cdrom_command_read_dma(dev); - else - scsi_cdrom_command_write_dma(dev); - } else { - scsi_cdrom_update_request_length(dev, len, block_len); - if (direction == 0) - scsi_cdrom_command_read(dev); - else - scsi_cdrom_command_write(dev); - } + if (direction == 0) + scsi_cdrom_command_read_dma(dev); + else + scsi_cdrom_command_write_dma(dev); + } else { + scsi_cdrom_update_request_length(dev, len, block_len); + if (direction == 0) + scsi_cdrom_command_read(dev); + else + scsi_cdrom_command_write(dev); + } } scsi_cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); + dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); } - static void scsi_cdrom_sense_clear(scsi_cdrom_t *dev, int command) { scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; } - static void scsi_cdrom_set_phase(scsi_cdrom_t *dev, uint8_t phase) { uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type != CDROM_BUS_SCSI) - return; + return; scsi_devices[scsi_bus][scsi_id].phase = phase; } - static void scsi_cdrom_cmd_error(scsi_cdrom_t *dev) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); dev->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * CDROM_TIME; + dev->callback = 50.0 * CDROM_TIME; scsi_cdrom_set_callback(dev); ui_sb_update_icon(SB_CDROM | dev->id, 0); scsi_cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq); } - static void scsi_cdrom_unit_attention(scsi_cdrom_t *dev) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * CDROM_TIME; + dev->callback = 50.0 * CDROM_TIME; scsi_cdrom_set_callback(dev); ui_sb_update_icon(SB_CDROM | dev->id, 0); scsi_cdrom_log("CD-ROM %i: UNIT ATTENTION\n", dev->id); } - static void scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, uint32_t len) { scsi_cdrom_log("CD-ROM %i: Allocated buffer length: %i\n", dev->id, len); if (!dev->buffer) - dev->buffer = (uint8_t *) malloc(len); + dev->buffer = (uint8_t *) malloc(len); } - static void scsi_cdrom_buf_free(scsi_cdrom_t *dev) { if (dev->buffer) { - scsi_cdrom_log("CD-ROM %i: Freeing buffer...\n", dev->id); - free(dev->buffer); - dev->buffer = NULL; + scsi_cdrom_log("CD-ROM %i: Freeing buffer...\n", dev->id); + free(dev->buffer); + dev->buffer = NULL; } } - static void scsi_cdrom_bus_master_error(scsi_common_t *sc) { @@ -876,123 +837,113 @@ scsi_cdrom_bus_master_error(scsi_common_t *sc) scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_not_ready(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_NOT_READY; - scsi_cdrom_asc = ASC_MEDIUM_NOT_PRESENT; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_MEDIUM_NOT_PRESENT; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_invalid_lun(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_INV_LUN; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_INV_LUN; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_illegal_opcode(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_ILLEGAL_OPCODE; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_ILLEGAL_OPCODE; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_lba_out_of_range(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_LBA_OUT_OF_RANGE; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_LBA_OUT_OF_RANGE; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_invalid_field(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); dev->status = 0x53; } - static void scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); dev->status = 0x53; } - static void scsi_cdrom_illegal_mode(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_incompatible_format(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_INCOMPATIBLE_FORMAT; - scsi_cdrom_ascq = 2; + scsi_cdrom_asc = ASC_INCOMPATIBLE_FORMAT; + scsi_cdrom_ascq = 2; scsi_cdrom_cmd_error(dev); } - static void scsi_cdrom_data_phase_error(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_DATA_PHASE_ERROR; - scsi_cdrom_ascq = 0; + scsi_cdrom_asc = ASC_DATA_PHASE_ERROR; + scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); } - static int scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *len) { - int ret = 0, data_pos = 0; - int i = 0, temp_len = 0; + int ret = 0, data_pos = 0; + int i = 0, temp_len = 0; uint32_t cdsize = 0; if (dev->drv->cd_status == CD_STATUS_EMPTY) { - scsi_cdrom_not_ready(dev); - return 0; + scsi_cdrom_not_ready(dev); + return 0; } cdsize = dev->drv->cdrom_capacity; if (dev->sector_pos >= cdsize) { - scsi_cdrom_log("CD-ROM %i: Trying to read from beyond the end of disc (%i >= %i)\n", dev->id, - dev->sector_pos, cdsize); - scsi_cdrom_lba_out_of_range(dev); - return -1; + scsi_cdrom_log("CD-ROM %i: Trying to read from beyond the end of disc (%i >= %i)\n", dev->id, + dev->sector_pos, cdsize); + scsi_cdrom_lba_out_of_range(dev); + return -1; } /* FIXME: Temporarily disabled this because the Triones ATAPI DMA driver seems to - always request a 4-sector read but sets the DMA bus master to transfer less - data than that. */ + always request a 4-sector read but sets the DMA bus master to transfer less + data than that. */ #if 0 if ((dev->sector_pos + dev->sector_len - 1) >= cdsize) { scsi_cdrom_log("CD-ROM %i: Trying to read to beyond the end of disc (%i >= %i)\n", dev->id, @@ -1003,27 +954,26 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l #endif dev->old_len = 0; - *len = 0; + *len = 0; for (i = 0; i < dev->requested_blocks; i++) { - ret = cdrom_readsector_raw(dev->drv, dev->buffer + data_pos, - dev->sector_pos + i, msf, type, flags, &temp_len); + ret = cdrom_readsector_raw(dev->drv, dev->buffer + data_pos, + dev->sector_pos + i, msf, type, flags, &temp_len); - data_pos += temp_len; - dev->old_len += temp_len; + data_pos += temp_len; + dev->old_len += temp_len; - *len += temp_len; + *len += temp_len; - if (!ret) { - scsi_cdrom_illegal_mode(dev); - return 0; - } + if (!ret) { + scsi_cdrom_illegal_mode(dev); + return 0; + } } return 1; } - static int scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) { @@ -1031,19 +981,19 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) int type = 0, flags = 0; if (dev->current_cdb[0] == GPCMD_READ_CD_MSF) - msf = 1; + msf = 1; if ((dev->current_cdb[0] == GPCMD_READ_CD_MSF) || (dev->current_cdb[0] == GPCMD_READ_CD)) { - type = (dev->current_cdb[1] >> 2) & 7; - flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); + type = (dev->current_cdb[1] >> 2) & 7; + flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); } else { - type = 8; - flags = 0x10; + type = 8; + flags = 0x10; } if (!dev->sector_len) { - scsi_cdrom_command_complete(dev); - return -1; + scsi_cdrom_command_complete(dev); + return -1; } scsi_cdrom_log("Reading %i blocks starting from %i...\n", dev->requested_blocks, dev->sector_pos); @@ -1053,12 +1003,12 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) scsi_cdrom_log("Read %i bytes of blocks...\n", *len); if (ret == -1) - return 0; + return 0; else if (!ret || ((dev->old_len != *len) && !first_batch)) { - if ((dev->old_len != *len) && !first_batch) - scsi_cdrom_illegal_mode(dev); + if ((dev->old_len != *len) && !first_batch) + scsi_cdrom_illegal_mode(dev); - return 0; + return 0; } dev->sector_pos += dev->requested_blocks; @@ -1067,131 +1017,129 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) return 1; } - /*SCSI Read DVD Structure*/ static int scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *packet, uint8_t *buf) { - int layer = packet[6]; + int layer = packet[6]; uint64_t total_sectors = 0; switch (format) { - case 0x00: /* Physical format information */ - if (dev->drv->cd_status == CD_STATUS_EMPTY) { - scsi_cdrom_not_ready(dev); - return 0; - } + case 0x00: /* Physical format information */ + if (dev->drv->cd_status == CD_STATUS_EMPTY) { + scsi_cdrom_not_ready(dev); + return 0; + } - total_sectors = (uint64_t) dev->drv->cdrom_capacity; + total_sectors = (uint64_t) dev->drv->cdrom_capacity; - if (layer != 0) { - scsi_cdrom_invalid_field(dev); - return 0; - } + if (layer != 0) { + scsi_cdrom_invalid_field(dev); + return 0; + } - total_sectors >>= 2; - if (total_sectors == 0) { - /* return -ASC_MEDIUM_NOT_PRESENT; */ - scsi_cdrom_not_ready(dev); - return 0; - } + total_sectors >>= 2; + if (total_sectors == 0) { + /* return -ASC_MEDIUM_NOT_PRESENT; */ + scsi_cdrom_not_ready(dev); + return 0; + } - buf[4] = 18; /* Length of Layer Information */ - buf[5] = 0; + buf[4] = 18; /* Length of Layer Information */ + buf[5] = 0; - buf[6] = 1; /* DVD-ROM, part version 1 */ - buf[7] = 0xf; /* 120mm disc, minimum rate unspecified */ - buf[8] = 1; /* one layer, read-only (per MMC-2 spec) */ - buf[9] = 0; /* default densities */ + buf[6] = 1; /* DVD-ROM, part version 1 */ + buf[7] = 0xf; /* 120mm disc, minimum rate unspecified */ + buf[8] = 1; /* one layer, read-only (per MMC-2 spec) */ + buf[9] = 0; /* default densities */ - /* FIXME: 0x30000 per spec? */ - buf[10] = 0x00; - buf[11] = 0x03; - buf[12] = buf[13] = 0; /* start sector */ + /* FIXME: 0x30000 per spec? */ + buf[10] = 0x00; + buf[11] = 0x03; + buf[12] = buf[13] = 0; /* start sector */ - buf[14] = 0x00; - buf[15] = (total_sectors >> 16) & 0xff; /* end sector */ - buf[16] = (total_sectors >> 8) & 0xff; - buf[17] = total_sectors & 0xff; + buf[14] = 0x00; + buf[15] = (total_sectors >> 16) & 0xff; /* end sector */ + buf[16] = (total_sectors >> 8) & 0xff; + buf[17] = total_sectors & 0xff; - buf[18] = 0x00; - buf[19] = (total_sectors >> 16) & 0xff; /* l0 end sector */ - buf[20] = (total_sectors >> 8) & 0xff; - buf[21] = total_sectors & 0xff; + buf[18] = 0x00; + buf[19] = (total_sectors >> 16) & 0xff; /* l0 end sector */ + buf[20] = (total_sectors >> 8) & 0xff; + buf[21] = total_sectors & 0xff; - /* 20 bytes of data + 4 byte header */ - return (20 + 4); + /* 20 bytes of data + 4 byte header */ + return (20 + 4); - case 0x01: /* DVD copyright information */ - buf[4] = 0; /* no copyright data */ - buf[5] = 0; /* no region restrictions */ + case 0x01: /* DVD copyright information */ + buf[4] = 0; /* no copyright data */ + buf[5] = 0; /* no region restrictions */ - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((4 + 2) >> 8) & 0xff; - buf[1] = (4 + 2) & 0xff; + /* Size of buffer, not including 2 byte size field */ + buf[0] = ((4 + 2) >> 8) & 0xff; + buf[1] = (4 + 2) & 0xff; - /* 4 byte header + 4 byte data */ - return (4 + 4); + /* 4 byte header + 4 byte data */ + return (4 + 4); - case 0x03: /* BCA information - invalid field for no BCA info */ - scsi_cdrom_invalid_field(dev); - return 0; + case 0x03: /* BCA information - invalid field for no BCA info */ + scsi_cdrom_invalid_field(dev); + return 0; - case 0x04: /* DVD disc manufacturing information */ - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((2048 + 2) >> 8) & 0xff; - buf[1] = (2048 + 2) & 0xff; + case 0x04: /* DVD disc manufacturing information */ + /* Size of buffer, not including 2 byte size field */ + buf[0] = ((2048 + 2) >> 8) & 0xff; + buf[1] = (2048 + 2) & 0xff; - /* 2k data + 4 byte header */ - return (2048 + 4); + /* 2k data + 4 byte header */ + return (2048 + 4); - case 0xff: - /* - * This lists all the command capabilities above. Add new ones - * in order and update the length and buffer return values. - */ + case 0xff: + /* + * This lists all the command capabilities above. Add new ones + * in order and update the length and buffer return values. + */ - buf[4] = 0x00; /* Physical format */ - buf[5] = 0x40; /* Not writable, is readable */ - buf[6] = ((20 + 4) >> 8) & 0xff; - buf[7] = (20 + 4) & 0xff; + buf[4] = 0x00; /* Physical format */ + buf[5] = 0x40; /* Not writable, is readable */ + buf[6] = ((20 + 4) >> 8) & 0xff; + buf[7] = (20 + 4) & 0xff; - buf[8] = 0x01; /* Copyright info */ - buf[9] = 0x40; /* Not writable, is readable */ - buf[10] = ((4 + 4) >> 8) & 0xff; - buf[11] = (4 + 4) & 0xff; + buf[8] = 0x01; /* Copyright info */ + buf[9] = 0x40; /* Not writable, is readable */ + buf[10] = ((4 + 4) >> 8) & 0xff; + buf[11] = (4 + 4) & 0xff; - buf[12] = 0x03; /* BCA info */ - buf[13] = 0x40; /* Not writable, is readable */ - buf[14] = ((188 + 4) >> 8) & 0xff; - buf[15] = (188 + 4) & 0xff; + buf[12] = 0x03; /* BCA info */ + buf[13] = 0x40; /* Not writable, is readable */ + buf[14] = ((188 + 4) >> 8) & 0xff; + buf[15] = (188 + 4) & 0xff; - buf[16] = 0x04; /* Manufacturing info */ - buf[17] = 0x40; /* Not writable, is readable */ - buf[18] = ((2048 + 4) >> 8) & 0xff; - buf[19] = (2048 + 4) & 0xff; + buf[16] = 0x04; /* Manufacturing info */ + buf[17] = 0x40; /* Not writable, is readable */ + buf[18] = ((2048 + 4) >> 8) & 0xff; + buf[19] = (2048 + 4) & 0xff; - /* Size of buffer, not including 2 byte size field */ - buf[6] = ((16 + 2) >> 8) & 0xff; - buf[7] = (16 + 2) & 0xff; + /* Size of buffer, not including 2 byte size field */ + buf[6] = ((16 + 2) >> 8) & 0xff; + buf[7] = (16 + 2) & 0xff; - /* data written + 4 byte header */ - return (16 + 4); + /* data written + 4 byte header */ + return (16 + 4); - default: /* TODO: formats beyond DVD-ROM requires */ - scsi_cdrom_invalid_field(dev); - return 0; + default: /* TODO: formats beyond DVD-ROM requires */ + scsi_cdrom_invalid_field(dev); + return 0; } } - static void scsi_cdrom_insert(void *p) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; if (!dev) - return; + return; dev->unit_attention = 1; /* Turn off the medium changed status. */ @@ -1199,48 +1147,47 @@ scsi_cdrom_insert(void *p) scsi_cdrom_log("CD-ROM %i: Media insert\n", dev->id); } - static int scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) { int ready = 0; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->request_length >> 5) & 7)); - scsi_cdrom_invalid_lun(dev); - return 0; - } + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { + scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", + dev->id, ((dev->request_length >> 5) & 7)); + scsi_cdrom_invalid_lun(dev); + return 0; + } } if (!(scsi_cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == CDROM_BUS_SCSI) ? "SCSI" : "ATAPI"); + scsi_cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], + (dev->drv->bus_type == CDROM_BUS_SCSI) ? "SCSI" : "ATAPI"); - scsi_cdrom_illegal_opcode(dev); - return 0; + scsi_cdrom_illegal_opcode(dev); + return 0; } if ((dev->drv->bus_type < CDROM_BUS_SCSI) && (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - scsi_cdrom_illegal_opcode(dev); - return 0; + scsi_cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); + scsi_cdrom_illegal_opcode(dev); + return 0; } if ((dev->drv->bus_type == CDROM_BUS_SCSI) && (scsi_cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - scsi_cdrom_illegal_opcode(dev); - return 0; + scsi_cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); + scsi_cdrom_illegal_opcode(dev); + return 0; } if ((dev->drv->cd_status == CD_STATUS_PLAYING) || (dev->drv->cd_status == CD_STATUS_PAUSED)) { - ready = 1; - goto skip_ready_check; + ready = 1; + goto skip_ready_check; } if (dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) - scsi_cdrom_insert((void *) dev); + scsi_cdrom_insert((void *) dev); ready = (dev->drv->cd_status != CD_STATUS_EMPTY); @@ -1249,42 +1196,42 @@ skip_ready_check: UNIT ATTENTION condition present, as we only use it to mark disc changes. */ if (!ready && dev->unit_attention) - dev->unit_attention = 0; + dev->unit_attention = 0; /* If the UNIT ATTENTION condition is set and the command does not allow execution under it, error out and report the condition. */ if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) { - /* scsi_cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention++; - scsi_cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", - dev->id, cdb[0]); - scsi_cdrom_unit_attention(dev); - return 0; - } + /* Only increment the unit attention phase if the command can not pass through it. */ + if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) { + /* scsi_cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); */ + dev->unit_attention++; + scsi_cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", + dev->id, cdb[0]); + scsi_cdrom_unit_attention(dev); + return 0; + } } else if (dev->unit_attention == 2) { - if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* scsi_cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); */ - dev->unit_attention = 0; - } + if (cdb[0] != GPCMD_REQUEST_SENSE) { + /* scsi_cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); */ + dev->unit_attention = 0; + } } /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - scsi_cdrom_sense_clear(dev, cdb[0]); + scsi_cdrom_sense_clear(dev, cdb[0]); /* Next it's time for NOT READY. */ if (!ready) - dev->media_status = MEC_MEDIA_REMOVAL; + dev->media_status = MEC_MEDIA_REMOVAL; else - dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; + dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; if ((scsi_cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) { - scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); - scsi_cdrom_not_ready(dev); - return 0; + scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); + scsi_cdrom_not_ready(dev); + return 0; } scsi_cdrom_log("CD-ROM %i: Continuing with command %02X\n", dev->id, cdb[0]); @@ -1292,7 +1239,6 @@ skip_ready_check: return 1; } - static void scsi_cdrom_rezero(scsi_cdrom_t *dev) { @@ -1300,101 +1246,95 @@ scsi_cdrom_rezero(scsi_cdrom_t *dev) cdrom_seek(dev->drv, 0); } - void scsi_cdrom_reset(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; if (!dev) - return; + return; scsi_cdrom_rezero(dev); - dev->status = 0; + dev->status = 0; dev->callback = 0.0; scsi_cdrom_set_callback(dev); - dev->phase = 1; + dev->phase = 1; dev->request_length = 0xEB14; - dev->packet_status = PHASE_NONE; + dev->packet_status = PHASE_NONE; dev->unit_attention = 0xff; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->cur_lun = SCSI_LUN_USE_CDB; } - static void scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - memcpy(buffer, dev->sense, alloc_length); + memset(buffer, 0, alloc_length); + memcpy(buffer, dev->sense, alloc_length); } buffer[0] = 0x70; if ((scsi_cdrom_sense_key > 0) && (dev->drv->cd_status == CD_STATUS_PLAYING_COMPLETED)) { - buffer[2]=SENSE_ILLEGAL_REQUEST; - buffer[12]=ASC_AUDIO_PLAY_OPERATION; - buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } else if ((scsi_cdrom_sense_key == 0) && ((dev->drv->cd_status == CD_STATUS_PAUSED) || - ((dev->drv->cd_status >= CD_STATUS_PLAYING) && (dev->drv->cd_status != CD_STATUS_STOPPED)))) { - buffer[2]=SENSE_ILLEGAL_REQUEST; - buffer[12]=ASC_AUDIO_PLAY_OPERATION; - buffer[13]=(dev->drv->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + buffer[2] = SENSE_ILLEGAL_REQUEST; + buffer[12] = ASC_AUDIO_PLAY_OPERATION; + buffer[13] = ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; + } else if ((scsi_cdrom_sense_key == 0) && ((dev->drv->cd_status == CD_STATUS_PAUSED) || ((dev->drv->cd_status >= CD_STATUS_PLAYING) && (dev->drv->cd_status != CD_STATUS_STOPPED)))) { + buffer[2] = SENSE_ILLEGAL_REQUEST; + buffer[12] = ASC_AUDIO_PLAY_OPERATION; + buffer[13] = (dev->drv->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; } else if (dev->unit_attention && (scsi_cdrom_sense_key == 0)) { - buffer[2]=SENSE_UNIT_ATTENTION; - buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[13]=0; + buffer[2] = SENSE_UNIT_ATTENTION; + buffer[12] = ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[13] = 0; } scsi_cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); if (buffer[2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ - dev->unit_attention = 0; + /* If the last remaining sense is unit attention, clear + that condition. */ + dev->unit_attention = 0; } /* Clear the sense stuff as per the spec. */ scsi_cdrom_sense_clear(dev, GPCMD_REQUEST_SENSE); } - void scsi_cdrom_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; if (dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) - scsi_cdrom_insert((void *) dev); + scsi_cdrom_insert((void *) dev); if ((dev->drv->cd_status == CD_STATUS_EMPTY) && dev->unit_attention) { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - dev->unit_attention = 0; + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + dev->unit_attention = 0; } /* Do *NOT* advance the unit attention phase. */ scsi_cdrom_request_sense(dev, buffer, alloc_length); } - static void scsi_cdrom_set_buf_len(scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - scsi_cdrom_log("CD-ROM %i: Actual transfer length: %i\n", dev->id, *BufLen); + if (*BufLen == -1) + *BufLen = *src_len; + else { + *BufLen = MIN(*src_len, *BufLen); + *src_len = *BufLen; + } + scsi_cdrom_log("CD-ROM %i: Actual transfer length: %i\n", dev->id, *BufLen); } } - static void scsi_cdrom_stop(scsi_common_t *sc) { @@ -1403,40 +1343,39 @@ scsi_cdrom_stop(scsi_common_t *sc) cdrom_stop(dev->drv); } - void scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; - int len, max_len, used_len, alloc_length, msf; - int pos = 0, i= 0, size_idx, idx = 0; - uint32_t feature; - unsigned preamble_len; - int toc_format, block_desc = 0; - int ret, format = 0; - int real_pos, track = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int32_t blen = 0, *BufLen; - uint8_t *b; - uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + int len, max_len, used_len, alloc_length, msf; + int pos = 0, i = 0, size_idx, idx = 0; + uint32_t feature; + unsigned preamble_len; + int toc_format, block_desc = 0; + int ret, format = 0; + int real_pos, track = 0; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + int32_t blen = 0, *BufLen; + uint8_t *b; + uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - dev->status &= ~ERR_STAT; + BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + dev->status &= ~ERR_STAT; } else { - BufLen = &blen; - dev->error = 0; + BufLen = &blen; + dev->error = 0; } - dev->packet_len = 0; + dev->packet_len = 0; dev->request_pos = 0; device_identify[7] = dev->id + 0x30; - device_identify_ex[7] = dev->id + 0x30; + device_identify_ex[7] = dev->id + 0x30; device_identify_ex[10] = EMU_VERSION_EX[0]; device_identify_ex[12] = EMU_VERSION_EX[2]; device_identify_ex[13] = EMU_VERSION_EX[3]; @@ -1444,1071 +1383,1071 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, dev->unit_attention); - scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length); + scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", + dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, dev->unit_attention); + scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length); - scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); + scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + cdb[8], cdb[9], cdb[10], cdb[11]); } - msf = cdb[1] & 2; + msf = cdb[1] & 2; dev->sector_len = 0; scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ if (scsi_cdrom_pre_execution_check(dev, cdb) == 0) - return; + return; switch (cdb[0]) { - case GPCMD_TEST_UNIT_READY: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - - case GPCMD_REZERO_UNIT: - scsi_cdrom_stop(sc); - dev->sector_pos = dev->sector_len = 0; - dev->drv->seek_diff = dev->drv->seek_pos; - cdrom_seek(dev->drv, 0); - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - - if (!max_len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, 256); - scsi_cdrom_set_buf_len(dev, BufLen, &max_len); - scsi_cdrom_request_sense(dev, dev->buffer, max_len); - scsi_cdrom_data_command_finish(dev, 18, 18, cdb[4], 0); - break; - - case GPCMD_SET_SPEED: - case GPCMD_SET_SPEED_ALT: - dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; - if (dev->drv->cur_speed < 1) - dev->drv->cur_speed = 1; - else if (dev->drv->cur_speed > dev->drv->speed) - dev->drv->cur_speed = dev->drv->speed; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - - case GPCMD_MECHANISM_STATUS: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - scsi_cdrom_buf_alloc(dev, 8); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - memset(dev->buffer, 0, 8); - dev->buffer[5] = 1; - - scsi_cdrom_data_command_finish(dev, 8, 8, len, 0); - break; - - case GPCMD_READ_TOC_PMA_ATIP: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 65536); - - toc_format = cdb[2] & 0xf; - - if (toc_format == 0) - toc_format = (cdb[9] >> 6) & 3; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (toc_format < 3) { - len = cdrom_read_toc(dev->drv, dev->buffer, toc_format, cdb[6], msf, max_len); - if (len == -1) { - /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - } else { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - /* scsi_cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", dev->id, - toc_format, ide->cylinder, dev->buffer[1]); */ - return; - - case GPCMD_READ_DISC_INFORMATION_TOSHIBA: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - scsi_cdrom_buf_alloc(dev, 65536); - - if ((!dev->drv->ops) && ((cdb[1] & 3) == 2)) { - scsi_cdrom_not_ready(dev); - return; - } - - memset(dev->buffer, 0, 4); - - cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - - len = 4; - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - - case GPCMD_READ_CD_OLD: - /* IMPORTANT: Convert the command to new read CD - for pass through purposes. */ - dev->current_cdb[0] = 0xbe; - /*FALLTHROUGH*/ - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - case GPCMD_READ_CD: - case GPCMD_READ_CD_MSF: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - alloc_length = 2048; - - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - msf = 0; - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, - dev->sector_pos); - msf = 0; - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, - dev->sector_pos); - msf = 0; - break; - case GPCMD_READ_CD_MSF: - alloc_length = 2856; - dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); - dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - - dev->sector_len -= dev->sector_pos; - dev->sector_len++; - - msf = 1; - - if ((cdb[9] & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - scsi_cdrom_invalid_field(dev); - return; - } - - /* If all the flag bits are cleared, then treat it as a non-data command. */ - if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) - dev->sector_len = 0; - else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { - scsi_cdrom_invalid_field(dev); - return; - } - break; - case GPCMD_READ_CD_OLD: - case GPCMD_READ_CD: - alloc_length = 2856; - dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - msf = 0; - - if ((cdb[9] & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - scsi_cdrom_invalid_field(dev); - return; - } - - /* If all the flag bits are cleared, then treat it as a non-data command. */ - if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) - dev->sector_len = 0; - else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { - scsi_cdrom_invalid_field(dev); - return; - } - break; - } - - if (!dev->sector_len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - /* scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - scsi_cdrom_buf_alloc(dev, dev->packet_len); - - dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); - - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1); - if (ret <= 0) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - scsi_cdrom_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - scsi_cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, - alloc_length, 0); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_CDROM | dev->id, 1); - else - ui_sb_update_icon(SB_CDROM | dev->id, 0); - return; - - case GPCMD_READ_HEADER: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = ((cdb[7] << 8) | cdb[8]); - scsi_cdrom_buf_alloc(dev, 8); - - dev->sector_len = 1; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; - if (msf) - real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); - else - real_pos = dev->sector_pos; - dev->buffer[0] = 1; /*2048 bytes user data*/ - dev->buffer[1] = dev->buffer[2] = dev->buffer[3] = 0; - dev->buffer[4] = (real_pos >> 24); - dev->buffer[5] = ((real_pos >> 16) & 0xff); - dev->buffer[6] = ((real_pos >> 8) & 0xff); - dev->buffer[7] = real_pos & 0xff; - - len = 8; - len = MIN(len, alloc_length); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else - block_desc = 0; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - scsi_cdrom_buf_alloc(dev, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - scsi_cdrom_buf_alloc(dev, 65536); - } - - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - memset(dev->buffer, 0, len); - alloc_length = len; - - /* This determines the media type ID to return - this is - a SCSI/ATAPI-specific thing, so it makes the most sense - to keep this here. - Also, the max_len variable is reused as this command - does otherwise not use it, to avoid having to declare - another variable. */ - if (dev->drv->cd_status == CD_STATUS_EMPTY) - max_len = 70; /* No media inserted. */ - else if (dev->drv->cdrom_capacity > 405000) - max_len = 65; /* DVD. */ - else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) - max_len = 1; /* Data CD. */ - else - max_len = 3; /* Audio or mixed-mode CD. */ - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_cdrom_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = len - 1; - dev->buffer[1] = max_len; - if (block_desc) - dev->buffer[3] = 8; - } else { - len = scsi_cdrom_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = (len - 2) >> 8; - dev->buffer[1] = (len - 2) & 255; - dev->buffer[2] = max_len; - if (block_desc) { - dev->buffer[6] = 0; - dev->buffer[7] = 8; - } - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - scsi_cdrom_buf_alloc(dev, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - scsi_cdrom_data_command_finish(dev, len, len, len, 1); - return; - - case GPCMD_GET_CONFIGURATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - /* XXX: could result in alignment problems in some architectures */ - feature = (cdb[2] << 8) | cdb[3]; - max_len = (cdb[7] << 8) | cdb[8]; - - /* only feature 0 is supported */ - if ((cdb[2] != 0) || (cdb[3] > 2)) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_buf_alloc(dev, 65536); - memset(dev->buffer, 0, max_len); - - alloc_length = 0; - b = dev->buffer; - - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (dev->drv->cd_status != CD_STATUS_EMPTY) { - len = dev->drv->cdrom_capacity; - if (len > CD_MAX_SECTORS) { - b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_DVD_ROM & 0xff; - ret = 1; - } else { - b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_CD_ROM & 0xff; - ret = 0; - } - } else - ret = 2; - - alloc_length = 8; - b += 8; - - if ((feature == 0) || ((cdb[1] & 3) < 2)) { - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - alloc_length += 4; - b += 4; - - for (i = 0; i < 2; i++) { - b[0] = (profiles[i] >> 8) & 0xff; - b[1] = profiles[i] & 0xff; - - if (ret == i) - b[2] |= 1; - - alloc_length += 4; - b += 4; - } - } - if ((feature == 1) || ((cdb[1] & 3) < 2)) { - b[1] = 1; - b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - b[7] = 1; - else - b[7] = 2; - b[8] = 1; - - alloc_length += 12; - b += 12; - } - if ((feature == 2) || ((cdb[1] & 3) < 2)) { - b[1] = 2; - b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 4; - - b[4] = 2; - - alloc_length += 8; - b += 8; - } - - dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff; - dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff; - dev->buffer[2] = ((alloc_length - 4) >> 8) & 0xff; - dev->buffer[3] = (alloc_length - 4) & 0xff; - - alloc_length = MIN(alloc_length, max_len); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); - break; - - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - scsi_cdrom_buf_alloc(dev, 8 + sizeof(gesn_event_header_t)); - - gesn_cdb = (void *) cdb; - gesn_event_header = (void *) dev->buffer; - - /* It is fine by the MMC spec to not support async mode operations. */ - if (!(gesn_cdb->polled & 0x01)) { - /* asynchronous mode */ - /* Only polling is supported, asynchronous mode is not. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - /* - * These are the supported events. - * - * We currently only support requests of the 'media' type. - * Notification class requests and supported event classes are bitmasks, - * but they are built from the same values as the "notification class" - * field. - */ - gesn_event_header->supported_events = 1 << GESN_MEDIA; - - /* - * We use |= below to set the class field; other bits in this byte - * are reserved now but this is useful to do if we have to use the - * reserved fields later. - */ - gesn_event_header->notification_class = 0; - - /* - * Responses to requests are to be based on request priority. The - * notification_class_request_type enum above specifies the - * priority: upper elements are higher prio than lower ones. - */ - if (gesn_cdb->class & (1 << GESN_MEDIA)) { - gesn_event_header->notification_class |= GESN_MEDIA; - - dev->buffer[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ - dev->buffer[5] = 1; /* Power Status (1 = Active) */ - dev->buffer[6] = 0; - dev->buffer[7] = 0; - used_len = 8; - } else { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - gesn_event_header->len = used_len - sizeof(*gesn_event_header); - - memmove(dev->buffer, gesn_event_header, 4); - - scsi_cdrom_set_buf_len(dev, BufLen, &used_len); - - scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); - break; - - case GPCMD_READ_DISC_INFORMATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 65536); - - memset(dev->buffer, 0, 34); - memset(dev->buffer, 1, 9); - dev->buffer[0] = 0; - dev->buffer[1] = 32; - dev->buffer[2] = 0xe; /* last session complete, disc finalized */ - dev->buffer[7] = 0x20; /* unrestricted use */ - dev->buffer[8] = 0x00; /* CD-ROM */ - - len=34; - len = MIN(len, max_len); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_READ_TRACK_INFORMATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 65536); - - track = ((uint32_t) cdb[2]) << 24; - track |= ((uint32_t) cdb[3]) << 16; - track |= ((uint32_t) cdb[4]) << 8; - track |= (uint32_t) cdb[5]; - - if (((cdb[1] & 0x03) != 1) || (track != 1)) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - len = 36; - - memset(dev->buffer, 0, 36); - dev->buffer[0] = 0; - dev->buffer[1] = 34; - dev->buffer[2] = 1; /* track number (LSB) */ - dev->buffer[3] = 1; /* session number (LSB) */ - dev->buffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ - dev->buffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ - dev->buffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ - - dev->buffer[24] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; /* track size */ - dev->buffer[25] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; /* track size */ - dev->buffer[26] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; /* track size */ - dev->buffer[27] = (dev->drv->cdrom_capacity - 1) & 0xff; /* track size */ - - if (len > max_len) { - len = max_len; - dev->buffer[0] = ((max_len - 2) >> 8) & 0xff; - dev->buffer[1] = (max_len - 2) & 0xff; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); - break; - - case GPCMD_AUDIO_TRACK_SEARCH: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9], cdb[1] & 1); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - - case GPCMD_TOSHIBA_PLAY_AUDIO: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_toshiba_audio_play(dev->drv, pos, cdb[9]); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_12: - case GPCMD_PLAY_AUDIO_MSF: - case GPCMD_PLAY_AUDIO_TRACK_INDEX: - case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: - case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: - len = 0; - - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[0]) { - case GPCMD_PLAY_AUDIO_10: - msf = 0; - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[7] << 8) | cdb[8]; - break; - case GPCMD_PLAY_AUDIO_12: - /* This is apparently deprecated in the ATAPI spec, and apparently - has been since 1995 (!). Hence I'm having to guess most of it. */ - msf = 0; - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - break; - case GPCMD_PLAY_AUDIO_MSF: - msf = 1; - pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - break; - case GPCMD_PLAY_AUDIO_TRACK_INDEX: - msf = 2; - if ((cdb[5] != 1) || (cdb[8] != 1)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = cdb[4]; - len = cdb[7]; - break; - case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: - msf = 0x100 | cdb[6]; - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[7] << 8) | cdb[8]; - break; - case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: - msf = 0x100 | cdb[10]; - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - break; - } - - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - - ret = cdrom_audio_play(dev->drv, pos, len, msf); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - - case GPCMD_READ_SUBCHANNEL: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = (cdb[1] >> 1) & 1; - - scsi_cdrom_buf_alloc(dev, 32); - - scsi_cdrom_log("CD-ROM %i: Getting page %i (%s)\n", dev->id, cdb[3], msf ? "MSF" : "LBA"); - - if (cdb[3] > 3) { - /* scsi_cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", dev->id, - cdb[3]); */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (!(cdb[2] & 0x40)) - alloc_length = 4; - else switch(cdb[3]) { - case 0: - /* SCSI-2: Q-type subchannel, ATAPI: reserved */ - alloc_length = (dev->drv->bus_type == CDROM_BUS_SCSI) ? 48 : 4; - break; - case 1: - alloc_length = 16; - break; - default: - alloc_length = 24; - break; - } - - len = alloc_length; - - memset(dev->buffer, 0, 24); - pos = 0; - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; /*Audio status*/ - dev->buffer[pos++] = 0; dev->buffer[pos++] = 0; /*Subchannel length*/ - /* Mode 0 = Q subchannel mode, first 16 bytes are indentical to mode 1 (current position), - the rest are stuff like ISRC etc., which can be all zeroes. */ - if (cdb[3] <= 3) { - dev->buffer[pos++] = cdb[3]; /*Format code*/ - - if (alloc_length != 4) { - dev->buffer[1] = cdrom_get_current_subchannel(dev->drv, &dev->buffer[4], msf); - dev->buffer[2] = alloc_length - 4; - } - - switch(dev->drv->cd_status) { - case CD_STATUS_PLAYING: - dev->buffer[1] = 0x11; - break; - case CD_STATUS_PAUSED: - dev->buffer[1] = 0x12; - break; - case CD_STATUS_DATA_ONLY: - dev->buffer[1] = 0x15; - break; - default: - dev->buffer[1] = 0x13; - break; - } - - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[1]); - } - - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_READ_SUBCODEQ_PLAYING_STATUS: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - - scsi_cdrom_buf_alloc(dev, alloc_length); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - len = alloc_length; - - memset(dev->buffer, 0, len); - dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_READ_DVD_STRUCTURE: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - - scsi_cdrom_buf_alloc(dev, alloc_length); - - if ((cdb[7] < 0xc0) && (dev->drv->cdrom_capacity <= CD_MAX_SECTORS)) { - scsi_cdrom_incompatible_format(dev); - scsi_cdrom_buf_free(dev); - return; - } - - memset(dev->buffer, 0, alloc_length); - - if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { - if (cdb[1] == 0) { - ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, dev->buffer); - dev->buffer[0] = (ret >> 8); - dev->buffer[1] = (ret & 0xff); - dev->buffer[2] = dev->buffer[3] = 0x00; - if (ret) { - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, - alloc_length, 0); - } else - scsi_cdrom_buf_free(dev); - return; - } - } else { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - break; - - case GPCMD_START_STOP_UNIT: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[4] & 3) { - case 0: /* Stop the disc. */ - scsi_cdrom_stop(sc); - break; - case 1: /* Start the disc and read the TOC. */ - /* This makes no sense under emulation as this would do - absolutely nothing, so just break. */ - break; - case 2: /* Eject the disc if possible. */ - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - break; - case 3: /* Load the disc (close tray). */ - cdrom_reload(dev->id); - break; - } - - scsi_cdrom_command_complete(dev); - break; - - case GPCMD_CADDY_EJECT: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - - case GPCMD_INQUIRY: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - scsi_cdrom_buf_alloc(dev, 65536); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - dev->buffer[idx++] = 05; - dev->buffer[idx++] = cdb[2]; - dev->buffer[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - scsi_cdrom_data_phase_error(dev); - scsi_cdrom_buf_free(dev); - return; - } - - dev->buffer[idx++] = 0x02; - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 20; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - dev->buffer[idx++] = 0x02; - dev->buffer[idx++] = 0x01; - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 68; - if (dev->drv->bus_type == CDROM_BUS_SCSI) - ide_padstr8(dev->buffer + idx, 8, "TOSHIBA"); /* Vendor */ - else - ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */ - idx += 8; - if (dev->drv->bus_type == CDROM_BUS_SCSI) - ide_padstr8(dev->buffer + idx, 40, "XM6201TASUN32XCD1103"); /* Product */ - else - ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ - idx += 40; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - scsi_cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(dev->buffer, 0, 8); - dev->buffer[0] = 5; /*CD-ROM*/ - dev->buffer[1] = 0x80; /*Removable*/ - - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - dev->buffer[2] = 0x02; - dev->buffer[3] = 0x02; - } - else { - dev->buffer[2] = 0x00; - dev->buffer[3] = 0x21; - } - - dev->buffer[4] = 31; - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - dev->buffer[6] = 1; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - } - - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - ide_padstr8(dev->buffer + 8, 8, "TOSHIBA"); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, "XM6201TASUN32XCD"); /* Product */ - ide_padstr8(dev->buffer + 32, 4, "1103"); /* Revision */ - } else { - ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */ - } - - idx = 36; - - if (max_len == 96) { - dev->buffer[4] = 91; - idx = 96; - } - } + case GPCMD_TEST_UNIT_READY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + break; + + case GPCMD_REZERO_UNIT: + scsi_cdrom_stop(sc); + dev->sector_pos = dev->sector_len = 0; + dev->drv->seek_diff = dev->drv->seek_pos; + cdrom_seek(dev->drv, 0); + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + break; + + case GPCMD_REQUEST_SENSE: + /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE + should forget about the not ready, and report unit attention straight away. */ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + max_len = cdb[4]; + + if (!max_len) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } + + scsi_cdrom_buf_alloc(dev, 256); + scsi_cdrom_set_buf_len(dev, BufLen, &max_len); + scsi_cdrom_request_sense(dev, dev->buffer, max_len); + scsi_cdrom_data_command_finish(dev, 18, 18, cdb[4], 0); + break; + + case GPCMD_SET_SPEED: + case GPCMD_SET_SPEED_ALT: + dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; + if (dev->drv->cur_speed < 1) + dev->drv->cur_speed = 1; + else if (dev->drv->cur_speed > dev->drv->speed) + dev->drv->cur_speed = dev->drv->speed; + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + break; + + case GPCMD_MECHANISM_STATUS: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + + scsi_cdrom_buf_alloc(dev, 8); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + memset(dev->buffer, 0, 8); + dev->buffer[5] = 1; + + scsi_cdrom_data_command_finish(dev, 8, 8, len, 0); + break; + + case GPCMD_READ_TOC_PMA_ATIP: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 65536); + + toc_format = cdb[2] & 0xf; + + if (toc_format == 0) + toc_format = (cdb[9] >> 6) & 3; + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } + + if (toc_format < 3) { + len = cdrom_read_toc(dev->drv, dev->buffer, toc_format, cdb[6], msf, max_len); + if (len == -1) { + /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + } else { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + /* scsi_cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", dev->id, + toc_format, ide->cylinder, dev->buffer[1]); */ + return; + + case GPCMD_READ_DISC_INFORMATION_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + scsi_cdrom_buf_alloc(dev, 65536); + + if ((!dev->drv->ops) && ((cdb[1] & 3) == 2)) { + scsi_cdrom_not_ready(dev); + return; + } + + memset(dev->buffer, 0, 4); + + cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + + len = 4; + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + + case GPCMD_READ_CD_OLD: + /* IMPORTANT: Convert the command to new read CD + for pass through purposes. */ + dev->current_cdb[0] = 0xbe; + /*FALLTHROUGH*/ + + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + alloc_length = 2048; + + switch (cdb[0]) { + case GPCMD_READ_6: + dev->sector_len = cdb[4]; + if (dev->sector_len == 0) + dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + msf = 0; + break; + case GPCMD_READ_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, + dev->sector_pos); + msf = 0; + break; + case GPCMD_READ_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, + dev->sector_pos); + msf = 0; + break; + case GPCMD_READ_CD_MSF: + alloc_length = 2856; + dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); + dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); + + dev->sector_len -= dev->sector_pos; + dev->sector_len++; + + msf = 1; + + if ((cdb[9] & 0xf8) == 0x08) { + /* 0x08 is an illegal mode */ + scsi_cdrom_invalid_field(dev); + return; + } + + /* If all the flag bits are cleared, then treat it as a non-data command. */ + if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) + dev->sector_len = 0; + else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { + scsi_cdrom_invalid_field(dev); + return; + } + break; + case GPCMD_READ_CD_OLD: + case GPCMD_READ_CD: + alloc_length = 2856; + dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + msf = 0; + + if ((cdb[9] & 0xf8) == 0x08) { + /* 0x08 is an illegal mode */ + scsi_cdrom_invalid_field(dev); + return; + } + + /* If all the flag bits are cleared, then treat it as a non-data command. */ + if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) + dev->sector_len = 0; + else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { + scsi_cdrom_invalid_field(dev); + return; + } + break; + } + + if (!dev->sector_len) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + /* scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } + + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT + matter anyway, this step should be identical and only the way the read dat is + transferred to the host should be different. */ + + dev->packet_len = max_len * alloc_length; + scsi_cdrom_buf_alloc(dev, dev->packet_len); + + dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); + + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1); + if (ret <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + scsi_cdrom_buf_free(dev); + return; + } + + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + scsi_cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, + alloc_length, 0); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_CDROM | dev->id, 1); + else + ui_sb_update_icon(SB_CDROM | dev->id, 0); + return; + + case GPCMD_READ_HEADER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = ((cdb[7] << 8) | cdb[8]); + scsi_cdrom_buf_alloc(dev, 8); + + dev->sector_len = 1; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + if (msf) + real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); + else + real_pos = dev->sector_pos; + dev->buffer[0] = 1; /*2048 bytes user data*/ + dev->buffer[1] = dev->buffer[2] = dev->buffer[3] = 0; + dev->buffer[4] = (real_pos >> 24); + dev->buffer[5] = ((real_pos >> 16) & 0xff); + dev->buffer[6] = ((real_pos >> 8) & 0xff); + dev->buffer[7] = real_pos & 0xff; + + len = 8; + len = MIN(len, alloc_length); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + if (dev->drv->bus_type == CDROM_BUS_SCSI) + block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + else + block_desc = 0; + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = cdb[4]; + scsi_cdrom_buf_alloc(dev, 256); + } else { + len = (cdb[8] | (cdb[7] << 8)); + scsi_cdrom_buf_alloc(dev, 65536); + } + + if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + + memset(dev->buffer, 0, len); + alloc_length = len; + + /* This determines the media type ID to return - this is + a SCSI/ATAPI-specific thing, so it makes the most sense + to keep this here. + Also, the max_len variable is reused as this command + does otherwise not use it, to avoid having to declare + another variable. */ + if (dev->drv->cd_status == CD_STATUS_EMPTY) + max_len = 70; /* No media inserted. */ + else if (dev->drv->cdrom_capacity > 405000) + max_len = 65; /* DVD. */ + else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) + max_len = 1; /* Data CD. */ + else + max_len = 3; /* Audio or mixed-mode CD. */ + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = scsi_cdrom_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = len - 1; + dev->buffer[1] = max_len; + if (block_desc) + dev->buffer[3] = 8; + } else { + len = scsi_cdrom_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = (len - 2) >> 8; + dev->buffer[1] = (len - 2) & 255; + dev->buffer[2] = max_len; + if (block_desc) { + dev->buffer[6] = 0; + dev->buffer[7] = 8; + } + } + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + + scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); + return; + + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); + + if (cdb[0] == GPCMD_MODE_SELECT_6) { + len = cdb[4]; + scsi_cdrom_buf_alloc(dev, 256); + } else { + len = (cdb[7] << 8) | cdb[8]; + scsi_cdrom_buf_alloc(dev, 65536); + } + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; + + scsi_cdrom_data_command_finish(dev, len, len, len, 1); + return; + + case GPCMD_GET_CONFIGURATION: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + /* XXX: could result in alignment problems in some architectures */ + feature = (cdb[2] << 8) | cdb[3]; + max_len = (cdb[7] << 8) | cdb[8]; + + /* only feature 0 is supported */ + if ((cdb[2] != 0) || (cdb[3] > 2)) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + + scsi_cdrom_buf_alloc(dev, 65536); + memset(dev->buffer, 0, max_len); + + alloc_length = 0; + b = dev->buffer; + + /* + * the number of sectors from the media tells us which profile + * to use as current. 0 means there is no media + */ + if (dev->drv->cd_status != CD_STATUS_EMPTY) { + len = dev->drv->cdrom_capacity; + if (len > CD_MAX_SECTORS) { + b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; + b[7] = MMC_PROFILE_DVD_ROM & 0xff; + ret = 1; + } else { + b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; + b[7] = MMC_PROFILE_CD_ROM & 0xff; + ret = 0; + } + } else + ret = 2; + + alloc_length = 8; + b += 8; + + if ((feature == 0) || ((cdb[1] & 3) < 2)) { + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 8; + + alloc_length += 4; + b += 4; + + for (i = 0; i < 2; i++) { + b[0] = (profiles[i] >> 8) & 0xff; + b[1] = profiles[i] & 0xff; + + if (ret == i) + b[2] |= 1; + + alloc_length += 4; + b += 4; + } + } + if ((feature == 1) || ((cdb[1] & 3) < 2)) { + b[1] = 1; + b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 8; + + if (dev->drv->bus_type == CDROM_BUS_SCSI) + b[7] = 1; + else + b[7] = 2; + b[8] = 1; + + alloc_length += 12; + b += 12; + } + if ((feature == 2) || ((cdb[1] & 3) < 2)) { + b[1] = 2; + b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 4; + + b[4] = 2; + + alloc_length += 8; + b += 8; + } + + dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff; + dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff; + dev->buffer[2] = ((alloc_length - 4) >> 8) & 0xff; + dev->buffer[3] = (alloc_length - 4) & 0xff; + + alloc_length = MIN(alloc_length, max_len); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); + break; + + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + scsi_cdrom_buf_alloc(dev, 8 + sizeof(gesn_event_header_t)); + + gesn_cdb = (void *) cdb; + gesn_event_header = (void *) dev->buffer; + + /* It is fine by the MMC spec to not support async mode operations. */ + if (!(gesn_cdb->polled & 0x01)) { + /* asynchronous mode */ + /* Only polling is supported, asynchronous mode is not. */ + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + + /* + * These are the supported events. + * + * We currently only support requests of the 'media' type. + * Notification class requests and supported event classes are bitmasks, + * but they are built from the same values as the "notification class" + * field. + */ + gesn_event_header->supported_events = 1 << GESN_MEDIA; + + /* + * We use |= below to set the class field; other bits in this byte + * are reserved now but this is useful to do if we have to use the + * reserved fields later. + */ + gesn_event_header->notification_class = 0; + + /* + * Responses to requests are to be based on request priority. The + * notification_class_request_type enum above specifies the + * priority: upper elements are higher prio than lower ones. + */ + if (gesn_cdb->class & (1 << GESN_MEDIA)) { + gesn_event_header->notification_class |= GESN_MEDIA; + + dev->buffer[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ + dev->buffer[5] = 1; /* Power Status (1 = Active) */ + dev->buffer[6] = 0; + dev->buffer[7] = 0; + used_len = 8; + } else { + gesn_event_header->notification_class = 0x80; /* No event available */ + used_len = sizeof(*gesn_event_header); + } + gesn_event_header->len = used_len - sizeof(*gesn_event_header); + + memmove(dev->buffer, gesn_event_header, 4); + + scsi_cdrom_set_buf_len(dev, BufLen, &used_len); + + scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); + break; + + case GPCMD_READ_DISC_INFORMATION: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 65536); + + memset(dev->buffer, 0, 34); + memset(dev->buffer, 1, 9); + dev->buffer[0] = 0; + dev->buffer[1] = 32; + dev->buffer[2] = 0xe; /* last session complete, disc finalized */ + dev->buffer[7] = 0x20; /* unrestricted use */ + dev->buffer[8] = 0x00; /* CD-ROM */ + + len = 34; + len = MIN(len, max_len); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + + case GPCMD_READ_TRACK_INFORMATION: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 65536); + + track = ((uint32_t) cdb[2]) << 24; + track |= ((uint32_t) cdb[3]) << 16; + track |= ((uint32_t) cdb[4]) << 8; + track |= (uint32_t) cdb[5]; + + if (((cdb[1] & 0x03) != 1) || (track != 1)) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + + len = 36; + + memset(dev->buffer, 0, 36); + dev->buffer[0] = 0; + dev->buffer[1] = 34; + dev->buffer[2] = 1; /* track number (LSB) */ + dev->buffer[3] = 1; /* session number (LSB) */ + dev->buffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ + dev->buffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ + dev->buffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ + + dev->buffer[24] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; /* track size */ + dev->buffer[25] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; /* track size */ + dev->buffer[26] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; /* track size */ + dev->buffer[27] = (dev->drv->cdrom_capacity - 1) & 0xff; /* track size */ + + if (len > max_len) { + len = max_len; + dev->buffer[0] = ((max_len - 2) >> 8) & 0xff; + dev->buffer[1] = (max_len - 2) & 0xff; + } + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); + break; + + case GPCMD_AUDIO_TRACK_SEARCH: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9], cdb[1] & 1); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + + case GPCMD_TOSHIBA_PLAY_AUDIO: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_toshiba_audio_play(dev->drv, pos, cdb[9]); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_12: + case GPCMD_PLAY_AUDIO_MSF: + case GPCMD_PLAY_AUDIO_TRACK_INDEX: + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: + len = 0; + + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + + switch (cdb[0]) { + case GPCMD_PLAY_AUDIO_10: + msf = 0; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[7] << 8) | cdb[8]; + break; + case GPCMD_PLAY_AUDIO_12: + /* This is apparently deprecated in the ATAPI spec, and apparently + has been since 1995 (!). Hence I'm having to guess most of it. */ + msf = 0; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + break; + case GPCMD_PLAY_AUDIO_MSF: + msf = 1; + pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + break; + case GPCMD_PLAY_AUDIO_TRACK_INDEX: + msf = 2; + if ((cdb[5] != 1) || (cdb[8] != 1)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = cdb[4]; + len = cdb[7]; + break; + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: + msf = 0x100 | cdb[6]; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[7] << 8) | cdb[8]; + break; + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: + msf = 0x100 | cdb[10]; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + break; + } + + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + + ret = cdrom_audio_play(dev->drv, pos, len, msf); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + + case GPCMD_READ_SUBCHANNEL: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + msf = (cdb[1] >> 1) & 1; + + scsi_cdrom_buf_alloc(dev, 32); + + scsi_cdrom_log("CD-ROM %i: Getting page %i (%s)\n", dev->id, cdb[3], msf ? "MSF" : "LBA"); + + if (cdb[3] > 3) { + /* scsi_cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", dev->id, + cdb[3]); */ + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + + if (!(cdb[2] & 0x40)) + alloc_length = 4; + else + switch (cdb[3]) { + case 0: + /* SCSI-2: Q-type subchannel, ATAPI: reserved */ + alloc_length = (dev->drv->bus_type == CDROM_BUS_SCSI) ? 48 : 4; + break; + case 1: + alloc_length = 16; + break; + default: + alloc_length = 24; + break; + } + + len = alloc_length; + + memset(dev->buffer, 0, 24); + pos = 0; + dev->buffer[pos++] = 0; + dev->buffer[pos++] = 0; /*Audio status*/ + dev->buffer[pos++] = 0; + dev->buffer[pos++] = 0; /*Subchannel length*/ + /* Mode 0 = Q subchannel mode, first 16 bytes are indentical to mode 1 (current position), + the rest are stuff like ISRC etc., which can be all zeroes. */ + if (cdb[3] <= 3) { + dev->buffer[pos++] = cdb[3]; /*Format code*/ + + if (alloc_length != 4) { + dev->buffer[1] = cdrom_get_current_subchannel(dev->drv, &dev->buffer[4], msf); + dev->buffer[2] = alloc_length - 4; + } + + switch (dev->drv->cd_status) { + case CD_STATUS_PLAYING: + dev->buffer[1] = 0x11; + break; + case CD_STATUS_PAUSED: + dev->buffer[1] = 0x12; + break; + case CD_STATUS_DATA_ONLY: + dev->buffer[1] = 0x15; + break; + default: + dev->buffer[1] = 0x13; + break; + } + + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[1]); + } + + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + + case GPCMD_READ_SUBCODEQ_PLAYING_STATUS: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + + scsi_cdrom_buf_alloc(dev, alloc_length); + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } + + if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } + + len = alloc_length; + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + + case GPCMD_READ_DVD_STRUCTURE: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + + scsi_cdrom_buf_alloc(dev, alloc_length); + + if ((cdb[7] < 0xc0) && (dev->drv->cdrom_capacity <= CD_MAX_SECTORS)) { + scsi_cdrom_incompatible_format(dev); + scsi_cdrom_buf_free(dev); + return; + } + + memset(dev->buffer, 0, alloc_length); + + if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { + if (cdb[1] == 0) { + ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, dev->buffer); + dev->buffer[0] = (ret >> 8); + dev->buffer[1] = (ret & 0xff); + dev->buffer[2] = dev->buffer[3] = 0x00; + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, + alloc_length, 0); + } else + scsi_cdrom_buf_free(dev); + return; + } + } else { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + break; + + case GPCMD_START_STOP_UNIT: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + + switch (cdb[4] & 3) { + case 0: /* Stop the disc. */ + scsi_cdrom_stop(sc); + break; + case 1: /* Start the disc and read the TOC. */ + /* This makes no sense under emulation as this would do + absolutely nothing, so just break. */ + break; + case 2: /* Eject the disc if possible. */ + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + break; + case 3: /* Load the disc (close tray). */ + cdrom_reload(dev->id); + break; + } + + scsi_cdrom_command_complete(dev); + break; + + case GPCMD_CADDY_EJECT: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + break; + + case GPCMD_INQUIRY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[3]; + max_len <<= 8; + max_len |= cdb[4]; + + scsi_cdrom_buf_alloc(dev, 65536); + + if (cdb[1] & 1) { + preamble_len = 4; + size_idx = 3; + + dev->buffer[idx++] = 05; + dev->buffer[idx++] = cdb[2]; + dev->buffer[idx++] = 0; + + idx++; + + switch (cdb[2]) { + case 0x00: + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 0x83; + break; + case 0x83: + if (idx + 24 > max_len) { + scsi_cdrom_data_phase_error(dev); + scsi_cdrom_buf_free(dev); + return; + } + + dev->buffer[idx++] = 0x02; + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 20; + ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ + idx += 20; + + if (idx + 72 > cdb[4]) + goto atapi_out; + dev->buffer[idx++] = 0x02; + dev->buffer[idx++] = 0x01; + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 68; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + ide_padstr8(dev->buffer + idx, 8, "TOSHIBA"); /* Vendor */ + else + ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */ + idx += 8; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + ide_padstr8(dev->buffer + idx, 40, "XM6201TASUN32XCD1103"); /* Product */ + else + ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ + idx += 40; + ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ + idx += 20; + break; + default: + scsi_cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + } else { + preamble_len = 5; + size_idx = 4; + + memset(dev->buffer, 0, 8); + dev->buffer[0] = 5; /*CD-ROM*/ + dev->buffer[1] = 0x80; /*Removable*/ + + if (dev->drv->bus_type == CDROM_BUS_SCSI) { + dev->buffer[2] = 0x02; + dev->buffer[3] = 0x02; + } else { + dev->buffer[2] = 0x00; + dev->buffer[3] = 0x21; + } + + dev->buffer[4] = 31; + if (dev->drv->bus_type == CDROM_BUS_SCSI) { + dev->buffer[6] = 1; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ + } + + if (dev->drv->bus_type == CDROM_BUS_SCSI) { + ide_padstr8(dev->buffer + 8, 8, "TOSHIBA"); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, "XM6201TASUN32XCD"); /* Product */ + ide_padstr8(dev->buffer + 32, 4, "1103"); /* Revision */ + } else { + ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ + ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */ + } + + idx = 36; + + if (max_len == 96) { + dev->buffer[4] = 91; + idx = 96; + } + } atapi_out: - dev->buffer[size_idx] = idx - preamble_len; - len=idx; + dev->buffer[size_idx] = idx - preamble_len; + len = idx; - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); - break; + scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); + break; - case GPCMD_PREVENT_REMOVAL: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; + case GPCMD_PREVENT_REMOVAL: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + break; #if 0 case GPCMD_PAUSE_RESUME_ALT: #endif - case GPCMD_PAUSE_RESUME: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); - scsi_cdrom_command_complete(dev); - break; + case GPCMD_PAUSE_RESUME: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); + scsi_cdrom_command_complete(dev); + break; - case GPCMD_STILL: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->drv->cd_status = CD_STATUS_PAUSED; - scsi_cdrom_command_complete(dev); - break; + case GPCMD_STILL: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->drv->cd_status = CD_STATUS_PAUSED; + scsi_cdrom_command_complete(dev); + break; - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + case GPCMD_SEEK_6: + case GPCMD_SEEK_10: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; - break; - } - dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos)); - cdrom_seek(dev->drv, pos); - scsi_cdrom_command_complete(dev); - break; + switch (cdb[0]) { + case GPCMD_SEEK_6: + pos = (cdb[2] << 8) | cdb[3]; + break; + case GPCMD_SEEK_10: + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + break; + } + dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos)); + cdrom_seek(dev->drv, pos); + scsi_cdrom_command_complete(dev); + break; - case GPCMD_READ_CDROM_CAPACITY: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + case GPCMD_READ_CDROM_CAPACITY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 8); + scsi_cdrom_buf_alloc(dev, 8); - /* IMPORTANT: What's returned is the last LBA block. */ - memset(dev->buffer, 0, 8); - dev->buffer[0] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; - dev->buffer[1] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; - dev->buffer[2] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; - dev->buffer[3] = (dev->drv->cdrom_capacity - 1) & 0xff; - dev->buffer[6] = 8; - len = 8; + /* IMPORTANT: What's returned is the last LBA block. */ + memset(dev->buffer, 0, 8); + dev->buffer[0] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; + dev->buffer[1] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; + dev->buffer[2] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; + dev->buffer[3] = (dev->drv->cdrom_capacity - 1) & 0xff; + dev->buffer[6] = 8; + len = 8; - scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; - case GPCMD_STOP_PLAY_SCAN: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + case GPCMD_STOP_PLAY_SCAN: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if (dev->drv->cd_status <= CD_STATUS_DATA_ONLY) { - scsi_cdrom_illegal_mode(dev); - break; - } + if (dev->drv->cd_status <= CD_STATUS_DATA_ONLY) { + scsi_cdrom_illegal_mode(dev); + break; + } - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - break; + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + break; - default: - scsi_cdrom_illegal_opcode(dev); - break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } /* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ if (scsi_cdrom_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) - scsi_cdrom_buf_free(dev); + scsi_cdrom_buf_free(dev); } - static void scsi_cdrom_command_stop(scsi_common_t *sc) { @@ -2518,165 +2457,160 @@ scsi_cdrom_command_stop(scsi_common_t *sc) scsi_cdrom_buf_free(dev); } - /* The command second phase function, needed for Mode Select. */ static uint8_t scsi_cdrom_phase_data_out(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; - uint16_t block_desc_len, pos; - uint16_t param_list_len; - uint16_t i = 0; + uint16_t block_desc_len, pos; + uint16_t param_list_len; + uint16_t i = 0; uint8_t error = 0; uint8_t page, page_len, hdr_len, val, old_val, ch; - switch(dev->current_cdb[0]) { - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { - hdr_len = 8; - param_list_len = dev->current_cdb[7]; - param_list_len <<= 8; - param_list_len |= dev->current_cdb[8]; - } else { - hdr_len = 4; - param_list_len = dev->current_cdb[4]; - } + switch (dev->current_cdb[0]) { + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { + hdr_len = 8; + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { + hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = dev->buffer[2]; - block_desc_len <<= 8; - block_desc_len |= dev->buffer[3]; - } else { - block_desc_len = dev->buffer[6]; - block_desc_len <<= 8; - block_desc_len |= dev->buffer[7]; - } - } else - block_desc_len = 0; + if (dev->drv->bus_type == CDROM_BUS_SCSI) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = dev->buffer[2]; + block_desc_len <<= 8; + block_desc_len |= dev->buffer[3]; + } else { + block_desc_len = dev->buffer[6]; + block_desc_len <<= 8; + block_desc_len |= dev->buffer[7]; + } + } else + block_desc_len = 0; - pos = hdr_len + block_desc_len; + pos = hdr_len + block_desc_len; - while(1) { - if (pos >= param_list_len) { - scsi_cdrom_log("CD-ROM %i: Buffer has only block descriptor\n", dev->id); - break; - } + while (1) { + if (pos >= param_list_len) { + scsi_cdrom_log("CD-ROM %i: Buffer has only block descriptor\n", dev->id); + break; + } - page = dev->buffer[pos] & 0x3F; - page_len = dev->buffer[pos + 1]; + page = dev->buffer[pos] & 0x3F; + page_len = dev->buffer[pos + 1]; - pos += 2; + pos += 2; - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { - scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); - error |= 1; - } else { - for (i = 0; i < page_len; i++) { - ch = scsi_cdrom_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); - error |= 1; - } - } - } - } + if (!(scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { + scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); + error |= 1; + } else { + for (i = 0; i < page_len; i++) { + ch = scsi_cdrom_mode_sense_pages_changeable.pages[page][i + 2]; + val = dev->buffer[pos + i]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else { + scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); + error |= 1; + } + } + } + } - pos += page_len; + pos += page_len; - if (dev->drv->bus_type == CDROM_BUS_SCSI) - val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = scsi_cdrom_mode_sense_pages_default.pages[page][0] & 0x80; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; + else + val = scsi_cdrom_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - scsi_cdrom_mode_sense_save(dev); + if (dev->do_page_save && val) + scsi_cdrom_mode_sense_save(dev); - if (pos >= dev->total_length) - break; - } + if (pos >= dev->total_length) + break; + } - if (error) { - scsi_cdrom_invalid_field_pl(dev); - scsi_cdrom_buf_free(dev); - return 0; - } - break; + if (error) { + scsi_cdrom_invalid_field_pl(dev); + scsi_cdrom_buf_free(dev); + return 0; + } + break; } scsi_cdrom_command_stop((scsi_common_t *) dev); return 1; } - static void scsi_cdrom_close(void *p) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; if (dev) - free(dev); + free(dev); } - static int scsi_cdrom_get_max(int ide_has_dma, int type) { int ret; - switch(type) { - case TYPE_PIO: - ret = ide_has_dma ? 4 : 0; - break; - case TYPE_SDMA: - ret = ide_has_dma ? 2 : -1; - break; - case TYPE_MDMA: - ret = ide_has_dma ? 2 : -1; - break; - case TYPE_UDMA: - ret = ide_has_dma ? 5 : -1; - break; - default: - ret = -1; - break; + switch (type) { + case TYPE_PIO: + ret = ide_has_dma ? 4 : 0; + break; + case TYPE_SDMA: + ret = ide_has_dma ? 2 : -1; + break; + case TYPE_MDMA: + ret = ide_has_dma ? 2 : -1; + break; + case TYPE_UDMA: + ret = ide_has_dma ? 5 : -1; + break; + default: + ret = -1; + break; } return ret; } - static int scsi_cdrom_get_timings(int ide_has_dma, int type) { int ret; - switch(type) { - case TIMINGS_DMA: - ret = ide_has_dma ? 120 : 0; - break; - case TIMINGS_PIO: - ret = ide_has_dma ? 120 : 0; - break; - case TIMINGS_PIO_FC: - ret = 0; - break; - default: - ret = 0; - break; + switch (type) { + case TIMINGS_DMA: + ret = ide_has_dma ? 120 : 0; + break; + case TIMINGS_PIO: + ret = ide_has_dma ? 120 : 0; + break; + case TIMINGS_PIO_FC: + ret = 0; + break; + default: + ret = 0; + break; } return ret; } - /** * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command */ @@ -2693,105 +2627,104 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) scsi_cdrom_log("ATAPI Identify: %s\n", device_identify); #endif - ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ #if 0 ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ #else - ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */ #endif - ide->buffer[49] = 0x200; /* LBA supported */ + ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ if (ide_has_dma) { - ide->buffer[71] = 30; - ide->buffer[72] = 30; - ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ - ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ + ide->buffer[71] = 30; + ide->buffer[72] = 30; + ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ + ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ } } - void scsi_cdrom_drive_reset(int c) { - cdrom_t *drv = &cdrom[c]; - scsi_cdrom_t *dev; + cdrom_t *drv = &cdrom[c]; + scsi_cdrom_t *dev; scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = drv->scsi_device_id & 0x0f; + ide_t *id; + uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = drv->scsi_device_id & 0x0f; if (drv->bus_type == CDROM_BUS_SCSI) { - /* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */ - if (scsi_bus >= SCSI_BUS_MAX) - return; + /* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */ + if (scsi_bus >= SCSI_BUS_MAX) + return; - /* Make sure to ignore any SCSI CD-ROM drive that has an out of range ID. */ - if (scsi_id >= SCSI_ID_MAX) - return; + /* Make sure to ignore any SCSI CD-ROM drive that has an out of range ID. */ + if (scsi_id >= SCSI_ID_MAX) + return; } /* Make sure to ignore any ATAPI CD-ROM drive that has an out of range IDE channel. */ if ((drv->bus_type == CDROM_BUS_ATAPI) && (drv->ide_channel > 7)) - return; + return; if (!drv->priv) { - drv->priv = (scsi_cdrom_t *) malloc(sizeof(scsi_cdrom_t)); - memset(drv->priv, 0, sizeof(scsi_cdrom_t)); + drv->priv = (scsi_cdrom_t *) malloc(sizeof(scsi_cdrom_t)); + memset(drv->priv, 0, sizeof(scsi_cdrom_t)); } dev = (scsi_cdrom_t *) drv->priv; - dev->id = c; + dev->id = c; dev->drv = drv; dev->cur_lun = SCSI_LUN_USE_CDB; - drv->insert = scsi_cdrom_insert; - drv->get_volume = scsi_cdrom_get_volume; + drv->insert = scsi_cdrom_insert; + drv->get_volume = scsi_cdrom_get_volume; drv->get_channel = scsi_cdrom_get_channel; - drv->close = scsi_cdrom_close; + drv->close = scsi_cdrom_close; scsi_cdrom_init(dev); if (drv->bus_type == CDROM_BUS_SCSI) { - /* SCSI CD-ROM, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + /* SCSI CD-ROM, attach to the SCSI bus. */ + sd = &scsi_devices[scsi_bus][scsi_id]; - sd->sc = (scsi_common_t *) dev; - sd->command = scsi_cdrom_command; - sd->request_sense = scsi_cdrom_request_sense_for_scsi; - sd->reset = scsi_cdrom_reset; - sd->phase_data_out = scsi_cdrom_phase_data_out; - sd->command_stop = scsi_cdrom_command_stop; - sd->type = SCSI_REMOVABLE_CDROM; + sd->sc = (scsi_common_t *) dev; + sd->command = scsi_cdrom_command; + sd->request_sense = scsi_cdrom_request_sense_for_scsi; + sd->reset = scsi_cdrom_reset; + sd->phase_data_out = scsi_cdrom_phase_data_out; + sd->command_stop = scsi_cdrom_command_stop; + sd->type = SCSI_REMOVABLE_CDROM; - scsi_cdrom_log("SCSI CD-ROM drive %i attached to SCSI ID %i\n", c, cdrom[c].scsi_device_id); + scsi_cdrom_log("SCSI CD-ROM drive %i attached to SCSI ID %i\n", c, cdrom[c].scsi_device_id); } else if (drv->bus_type == CDROM_BUS_ATAPI) { - /* ATAPI CD-ROM, attach to the IDE bus. */ - id = ide_get_drive(drv->ide_channel); - /* If the IDE channel is initialized, we attach to it, - otherwise, we do nothing - it's going to be a drive - that's not attached to anything. */ - if (id) { - id->sc = (scsi_common_t *) dev; - id->get_max = scsi_cdrom_get_max; - id->get_timings = scsi_cdrom_get_timings; - id->identify = scsi_cdrom_identify; - id->stop = scsi_cdrom_stop; - id->packet_command = scsi_cdrom_command; - id->device_reset = scsi_cdrom_reset; - id->phase_data_out = scsi_cdrom_phase_data_out; - id->command_stop = scsi_cdrom_command_stop; - id->bus_master_error = scsi_cdrom_bus_master_error; - id->interrupt_drq = 0; + /* ATAPI CD-ROM, attach to the IDE bus. */ + id = ide_get_drive(drv->ide_channel); + /* If the IDE channel is initialized, we attach to it, + otherwise, we do nothing - it's going to be a drive + that's not attached to anything. */ + if (id) { + id->sc = (scsi_common_t *) dev; + id->get_max = scsi_cdrom_get_max; + id->get_timings = scsi_cdrom_get_timings; + id->identify = scsi_cdrom_identify; + id->stop = scsi_cdrom_stop; + id->packet_command = scsi_cdrom_command; + id->device_reset = scsi_cdrom_reset; + id->phase_data_out = scsi_cdrom_phase_data_out; + id->command_stop = scsi_cdrom_command_stop; + id->bus_master_error = scsi_cdrom_bus_master_error; + id->interrupt_drq = 0; - ide_atapi_attach(id); - } + ide_atapi_attach(id); + } - scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel); + scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel); } } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 09e44a914..ad87c7460 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -26,85 +26,76 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> +scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX]; -scsi_device_t scsi_devices[SCSI_BUS_MAX][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 }; - +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(scsi_device_t *dev, uint8_t *cdb) { if (dev->command) { - dev->command(dev->sc, cdb); + dev->command(dev->sc, cdb); - if (dev->sc->status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; + if (dev->sc->status & ERR_STAT) + return SCSI_STATUS_CHECK_CONDITION; + else + return SCSI_STATUS_OK; } else - return SCSI_STATUS_CHECK_CONDITION; + return SCSI_STATUS_CHECK_CONDITION; } - double scsi_device_get_callback(scsi_device_t *dev) { if (dev->sc) - return dev->sc->callback; + return dev->sc->callback; else - return -1.0; + return -1.0; } - uint8_t * scsi_device_sense(scsi_device_t *dev) { if (dev->sc) - return dev->sc->sense; + return dev->sc->sense; else - return scsi_null_device_sense; + return scsi_null_device_sense; } - void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer, uint8_t alloc_length) { if (dev->request_sense) - dev->request_sense(dev->sc, buffer, alloc_length); + dev->request_sense(dev->sc, buffer, alloc_length); else - memcpy(buffer, scsi_null_device_sense, alloc_length); + memcpy(buffer, scsi_null_device_sense, alloc_length); } - void scsi_device_reset(scsi_device_t *dev) { if (dev->reset) - dev->reset(dev->sc); + dev->reset(dev->sc); } - int scsi_device_present(scsi_device_t *dev) { if (dev->type == SCSI_NONE) - return 0; + return 0; else - return 1; + return 1; } - int scsi_device_valid(scsi_device_t *dev) { if (dev->sc) - return 1; + return 1; else - return 0; + return 0; } - int scsi_device_cdb_length(scsi_device_t *dev) { @@ -112,95 +103,89 @@ scsi_device_cdb_length(scsi_device_t *dev) return 12; } - void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb) { if (!dev->sc) { - dev->phase = SCSI_PHASE_STATUS; - dev->status = SCSI_STATUS_CHECK_CONDITION; - return; + dev->phase = SCSI_PHASE_STATUS; + dev->status = SCSI_STATUS_CHECK_CONDITION; + return; } /* Finally, execute the SCSI command immediately and get the transfer length. */ - dev->phase = SCSI_PHASE_COMMAND; + dev->phase = SCSI_PHASE_COMMAND; dev->status = scsi_device_target_command(dev, cdb); } - void scsi_device_command_stop(scsi_device_t *dev) { if (dev->command_stop) { - dev->command_stop(dev->sc); - dev->status = SCSI_STATUS_OK; + dev->command_stop(dev->sc); + dev->status = SCSI_STATUS_OK; } } - void scsi_device_command_phase1(scsi_device_t *dev) { if (!dev->sc) - return; + return; /* Call the second phase. */ if (dev->phase == SCSI_PHASE_DATA_OUT) { - if (dev->phase_data_out) - dev->phase_data_out(dev->sc); + if (dev->phase_data_out) + dev->phase_data_out(dev->sc); } else - scsi_device_command_stop(dev); + scsi_device_command_stop(dev); if (dev->sc->status & ERR_STAT) - dev->status = SCSI_STATUS_CHECK_CONDITION; + dev->status = SCSI_STATUS_CHECK_CONDITION; else - dev->status = SCSI_STATUS_OK; + dev->status = SCSI_STATUS_OK; } - /* When LUN is FF, there has been no IDENTIFY message, otherwise there has been one. */ void scsi_device_identify(scsi_device_t *dev, uint8_t lun) { if ((dev == NULL) || (dev->type == SCSI_NONE) || !dev->sc) - return; + return; dev->sc->cur_lun = lun; /* TODO: This should return a value, should IDENTIFY fail due to a - a LUN not supported by the target. */ + a LUN not supported by the target. */ } - void scsi_device_close_all(void) { - int i, j; + int i, j; scsi_device_t *dev; for (i = 0; i < SCSI_BUS_MAX; i++) { - for (j = 0; j < SCSI_ID_MAX; j++) { - dev = &(scsi_devices[i][j]); - if (dev->command_stop && dev->sc) - dev->command_stop(dev->sc); - } + for (j = 0; j < SCSI_ID_MAX; j++) { + dev = &(scsi_devices[i][j]); + if (dev->command_stop && dev->sc) + dev->command_stop(dev->sc); + } } } - void scsi_device_init(void) { - int i, j; + int i, j; scsi_device_t *dev; for (i = 0; i < SCSI_BUS_MAX; i++) { - for (j = 0; j < SCSI_ID_MAX; j++) { - dev = &(scsi_devices[i][j]); + for (j = 0; j < SCSI_ID_MAX; j++) { + dev = &(scsi_devices[i][j]); - memset(dev, 0, sizeof(scsi_device_t)); - dev->type = SCSI_NONE; - } + memset(dev, 0, sizeof(scsi_device_t)); + dev->type = SCSI_NONE; + } } } diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 133c23997..ccf35a2c8 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -33,69 +33,67 @@ #include <86box/scsi_disk.h> #include <86box/version.h> - #define scsi_disk_sense_error dev->sense[0] -#define scsi_disk_sense_key dev->sense[2] -#define scsi_disk_asc dev->sense[12] -#define scsi_disk_ascq dev->sense[13] - +#define scsi_disk_sense_key dev->sense[2] +#define scsi_disk_asc dev->sense[12] +#define scsi_disk_ascq dev->sense[13] /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ const uint8_t scsi_disk_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + IMPLEMENTED | CHECK_READY, /* 0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ + IMPLEMENTED, /* 0x15 */ + IMPLEMENTED | SCSI_ONLY, /* 0x16 */ + IMPLEMENTED | SCSI_ONLY, /* 0x17 */ 0, 0, - IMPLEMENTED, /* 0x1A */ + IMPLEMENTED, /* 0x1A */ 0, 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ + IMPLEMENTED, /* 0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + IMPLEMENTED | CHECK_READY, /* 0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + IMPLEMENTED | CHECK_READY, /* 0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ + IMPLEMENTED | CHECK_READY, /* 0x41 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ + IMPLEMENTED, /* 0x55 */ 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ + IMPLEMENTED, /* 0x5A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ + IMPLEMENTED | CHECK_READY, /* 0xAA */ 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + IMPLEMENTED | CHECK_READY, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ + IMPLEMENTED, /* 0xBD */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -103,51 +101,44 @@ const uint8_t scsi_disk_command_flags[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -uint64_t scsi_disk_mode_sense_page_flags = (GPMODEP_FORMAT_DEVICE_PAGE | - GPMODEP_RIGID_DISK_PAGE | - GPMODEP_UNK_VENDOR_PAGE | - GPMODEP_ALL_PAGES); +uint64_t scsi_disk_mode_sense_page_flags = (GPMODEP_FORMAT_DEVICE_PAGE | GPMODEP_RIGID_DISK_PAGE | GPMODEP_UNK_VENDOR_PAGE | GPMODEP_ALL_PAGES); /* This should be done in a better way but for time being, it's been done this way so it's not as huge and more readable. */ -static const mode_sense_pages_t scsi_disk_mode_sense_pages_default = -{ { [GPMODE_FORMAT_DEVICE_PAGE] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [GPMODE_RIGID_DISK_PAGE ] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 200, 0xff, 0xff, 0xff, 0, 0, 0, 0x15, 0x18, 0, 0 }, - [GPMODE_UNK_VENDOR_PAGE ] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } -} }; - -static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable = -{ { [GPMODE_FORMAT_DEVICE_PAGE] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [GPMODE_RIGID_DISK_PAGE ] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [GPMODE_UNK_VENDOR_PAGE ] = { 0xB0, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } -} }; +static const mode_sense_pages_t scsi_disk_mode_sense_pages_default = { + {[GPMODE_FORMAT_DEVICE_PAGE] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + [GPMODE_RIGID_DISK_PAGE] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 200, 0xff, 0xff, 0xff, 0, 0, 0, 0x15, 0x18, 0, 0 }, + [GPMODE_UNK_VENDOR_PAGE] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }} +}; +static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable = { + {[GPMODE_FORMAT_DEVICE_PAGE] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + [GPMODE_RIGID_DISK_PAGE] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + [GPMODE_UNK_VENDOR_PAGE] = { 0xB0, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }} +}; #ifdef ENABLE_SCSI_DISK_LOG int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG; - static void scsi_disk_log(const char *fmt, ...) { va_list ap; if (scsi_disk_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define scsi_disk_log(fmt, ...) +# define scsi_disk_log(fmt, ...) #endif - void scsi_disk_mode_sense_load(scsi_disk_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); memcpy(&dev->ms_pages_saved, &scsi_disk_mode_sense_pages_default, sizeof(mode_sense_pages_t)); @@ -156,91 +147,93 @@ scsi_disk_mode_sense_load(scsi_disk_t *dev) sprintf(file_name, "scsi_disk_%02i_mode_sense.bin", dev->id); f = plat_fopen(nvr_path(file_name), "rb"); if (f) { - if (fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, f) != 0x18) - fatal("scsi_disk_mode_sense_load(): Error reading data\n"); - fclose(f); + if (fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, f) != 0x18) + fatal("scsi_disk_mode_sense_load(): Error reading data\n"); + fclose(f); } } - void scsi_disk_mode_sense_save(scsi_disk_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(file_name, 0, 512); sprintf(file_name, "scsi_disk_%02i_mode_sense.bin", dev->id); f = plat_fopen(nvr_path(file_name), "wb"); if (f) { - fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); - fclose(f); + fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); + fclose(f); } } - /*SCSI Mode Sense 6/10*/ uint8_t scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { if (page_control == 1) - return scsi_disk_mode_sense_pages_changeable.pages[page][pos]; + return scsi_disk_mode_sense_pages_changeable.pages[page][pos]; - if (page == GPMODE_RIGID_DISK_PAGE) switch (page_control) { - /* Rigid disk geometry page. */ - case 0: - case 2: - case 3: - switch(pos) { - case 0: - case 1: - default: - return scsi_disk_mode_sense_pages_default.pages[page][pos]; - case 2: - case 6: - case 9: - return (dev->drv->tracks >> 16) & 0xff; - case 3: - case 7: - case 10: - return (dev->drv->tracks >> 8) & 0xff; - case 4: - case 8: - case 11: - return dev->drv->tracks & 0xff; - case 5: - return dev->drv->hpc & 0xff; - } - break; - } else if (page == GPMODE_FORMAT_DEVICE_PAGE) switch (page_control) { - /* Format device page. */ - case 0: - case 2: - case 3: - switch(pos) { - case 0: - case 1: - default: - return scsi_disk_mode_sense_pages_default.pages[page][pos]; - /* Actual sectors + the 1 "alternate sector" we report. */ - case 10: - return ((dev->drv->spt + 1) >> 8) & 0xff; - case 11: - return (dev->drv->spt + 1) & 0xff; - } - break; - } else switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - case 2: - return scsi_disk_mode_sense_pages_default.pages[page][pos]; - } + if (page == GPMODE_RIGID_DISK_PAGE) + switch (page_control) { + /* Rigid disk geometry page. */ + case 0: + case 2: + case 3: + switch (pos) { + case 0: + case 1: + default: + return scsi_disk_mode_sense_pages_default.pages[page][pos]; + case 2: + case 6: + case 9: + return (dev->drv->tracks >> 16) & 0xff; + case 3: + case 7: + case 10: + return (dev->drv->tracks >> 8) & 0xff; + case 4: + case 8: + case 11: + return dev->drv->tracks & 0xff; + case 5: + return dev->drv->hpc & 0xff; + } + break; + } + else if (page == GPMODE_FORMAT_DEVICE_PAGE) + switch (page_control) { + /* Format device page. */ + case 0: + case 2: + case 3: + switch (pos) { + case 0: + case 1: + default: + return scsi_disk_mode_sense_pages_default.pages[page][pos]; + /* Actual sectors + the 1 "alternate sector" we report. */ + case 10: + return ((dev->drv->spt + 1) >> 8) & 0xff; + case 11: + return (dev->drv->spt + 1) & 0xff; + } + break; + } + else + switch (page_control) { + case 0: + case 3: + return dev->ms_pages_saved.pages[page][pos]; + case 2: + return scsi_disk_mode_sense_pages_default.pages[page][pos]; + } return 0; } - uint32_t scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) { @@ -254,45 +247,43 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, size = hdd_image_get_last_sector(dev->id); if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = (size >> 16) & 0xff; /* Number of blocks (0 = all). */ - buf[pos++] = (size >> 8) & 0xff; - buf[pos++] = size & 0xff; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ - buf[pos++] = 2; - buf[pos++] = 0; + buf[pos++] = 1; /* Density code. */ + buf[pos++] = (size >> 16) & 0xff; /* Number of blocks (0 = all). */ + buf[pos++] = (size >> 8) & 0xff; + buf[pos++] = size & 0xff; + buf[pos++] = 0; /* Reserved. */ + buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ + buf[pos++] = 2; + buf[pos++] = 0; } for (i = 0; i < 0x40; i++) { 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; - scsi_disk_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 2 + j); - } - } + 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; + scsi_disk_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + for (j = 0; j < msplen; j++) + buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 2 + j); + } + } } return pos; } - static void scsi_disk_command_common(scsi_disk_t *dev) { dev->status = BUSY_STAT; - dev->phase = 1; + dev->phase = 1; if (dev->packet_status == PHASE_COMPLETE) - dev->callback = 0.0; + dev->callback = 0.0; else - dev->callback = -1.0; /* Speed depends on SCSI controller */ + dev->callback = -1.0; /* Speed depends on SCSI controller */ } - static void scsi_disk_command_complete(scsi_disk_t *dev) { @@ -301,7 +292,6 @@ scsi_disk_command_complete(scsi_disk_t *dev) scsi_disk_command_common(dev); } - static void scsi_disk_command_read_dma(scsi_disk_t *dev) { @@ -309,7 +299,6 @@ scsi_disk_command_read_dma(scsi_disk_t *dev) scsi_disk_command_common(dev); } - static void scsi_disk_command_write_dma(scsi_disk_t *dev) { @@ -317,151 +306,139 @@ scsi_disk_command_write_dma(scsi_disk_t *dev) scsi_disk_command_common(dev); } - static void scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int alloc_len, int direction) { scsi_disk_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->id, - dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; + if (alloc_len < len) + len = alloc_len; } if (len == 0) - scsi_disk_command_complete(dev); + scsi_disk_command_complete(dev); else { - if (direction == 0) - scsi_disk_command_read_dma(dev); - else - scsi_disk_command_write_dma(dev); + if (direction == 0) + scsi_disk_command_read_dma(dev); + else + scsi_disk_command_write_dma(dev); } } - static void scsi_disk_sense_clear(scsi_disk_t *dev, int command) { scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; } - static void scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase) { uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + uint8_t scsi_id = dev->drv->scsi_id & 0x0f; if (dev->drv->bus != HDD_BUS_SCSI) - return; + return; scsi_devices[scsi_bus][scsi_id].phase = phase; } - static void scsi_disk_cmd_error(scsi_disk_t *dev) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((scsi_disk_sense_key & 0xf) << 4) | ABRT_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; + dev->error = ((scsi_disk_sense_key & 0xf) << 4) | ABRT_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * SCSI_TIME; + dev->callback = 50.0 * SCSI_TIME; ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); scsi_disk_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); } - static void scsi_disk_invalid_lun(scsi_disk_t *dev) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_INV_LUN; - scsi_disk_ascq = 0; + scsi_disk_asc = ASC_INV_LUN; + scsi_disk_ascq = 0; scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); scsi_disk_cmd_error(dev); } - static void scsi_disk_illegal_opcode(scsi_disk_t *dev) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_ILLEGAL_OPCODE; - scsi_disk_ascq = 0; + scsi_disk_asc = ASC_ILLEGAL_OPCODE; + scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); } - static void scsi_disk_lba_out_of_range(scsi_disk_t *dev) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_LBA_OUT_OF_RANGE; - scsi_disk_ascq = 0; + scsi_disk_asc = ASC_LBA_OUT_OF_RANGE; + scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); } - static void scsi_disk_invalid_field(scsi_disk_t *dev) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_INV_FIELD_IN_CMD_PACKET; - scsi_disk_ascq = 0; + scsi_disk_asc = ASC_INV_FIELD_IN_CMD_PACKET; + scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); dev->status = 0x53; } - static void scsi_disk_invalid_field_pl(scsi_disk_t *dev) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - scsi_disk_ascq = 0; + scsi_disk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); dev->status = 0x53; } - static void scsi_disk_data_phase_error(scsi_disk_t *dev) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_disk_asc = ASC_DATA_PHASE_ERROR; - scsi_disk_ascq = 0; + scsi_disk_asc = ASC_DATA_PHASE_ERROR; + scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); } - static int scsi_disk_pre_execution_check(scsi_disk_t *dev, uint8_t *cdb) { if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->request_length >> 5) & 7)); - scsi_disk_invalid_lun(dev); - return 0; + scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", + dev->id, ((dev->request_length >> 5) & 7)); + scsi_disk_invalid_lun(dev); + return 0; } if (!(scsi_disk_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X\n", dev->id, cdb[0]); - scsi_disk_illegal_opcode(dev); - return 0; + scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X\n", dev->id, cdb[0]); + scsi_disk_illegal_opcode(dev); + return 0; } /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - scsi_disk_sense_clear(dev, cdb[0]); + scsi_disk_sense_clear(dev, cdb[0]); scsi_disk_log("SCSI HD %i: Continuing with command\n", dev->id); return 1; } - static void scsi_disk_seek(scsi_disk_t *dev, uint32_t pos) { @@ -469,46 +446,43 @@ scsi_disk_seek(scsi_disk_t *dev, uint32_t pos) hdd_image_seek(dev->id, pos); } - static void scsi_disk_rezero(scsi_disk_t *dev) { if (dev->id == 0xff) - return; + return; dev->sector_pos = dev->sector_len = 0; scsi_disk_seek(dev, 0); } - static void scsi_disk_reset(scsi_common_t *sc) { scsi_disk_t *dev = (scsi_disk_t *) sc; scsi_disk_rezero(dev); - dev->status = 0; - dev->callback = 0.0; + dev->status = 0; + dev->callback = 0.0; dev->packet_status = PHASE_NONE; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->cur_lun = SCSI_LUN_USE_CDB; } - void scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { - buffer[1] = scsi_disk_sense_key; - buffer[2] = scsi_disk_asc; - buffer[3] = scsi_disk_ascq; - } + memset(buffer, 0, alloc_length); + if (!desc) + memcpy(buffer, dev->sense, alloc_length); + else { + buffer[1] = scsi_disk_sense_key; + buffer[2] = scsi_disk_asc; + buffer[3] = scsi_disk_ascq; + } } else - return; + return; buffer[0] = 0x70; @@ -518,7 +492,6 @@ scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length, scsi_disk_sense_clear(dev, GPCMD_REQUEST_SENSE); } - static void scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { @@ -527,55 +500,51 @@ scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t all scsi_disk_request_sense(dev, buffer, alloc_length, 0); } - static void scsi_disk_set_buf_len(scsi_disk_t *dev, int32_t *BufLen, int32_t *src_len) { if (*BufLen == -1) - *BufLen = *src_len; + *BufLen = *src_len; else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; + *BufLen = MIN(*src_len, *BufLen); + *src_len = *BufLen; } scsi_disk_log("SCSI HD %i: Actual transfer length: %i\n", dev->id, *BufLen); } - static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log("SCSI HD %i: Allocated buffer length: %i\n", dev->id, len); if (!dev->temp_buffer) - dev->temp_buffer = (uint8_t *) malloc(len); + dev->temp_buffer = (uint8_t *) malloc(len); } - static void scsi_disk_buf_free(scsi_disk_t *dev) { if (dev->temp_buffer) { - scsi_disk_log("SCSI HD %i: Freeing buffer...\n", dev->id); - free(dev->temp_buffer); - dev->temp_buffer = NULL; + scsi_disk_log("SCSI HD %i: Freeing buffer...\n", dev->id); + free(dev->temp_buffer); + dev->temp_buffer = NULL; } } - static void scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) { scsi_disk_t *dev = (scsi_disk_t *) sc; - int32_t *BufLen; - int32_t len, max_len, alloc_length; - int pos = 0; - int idx = 0; - unsigned size_idx, preamble_len; - uint32_t last_sector = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int block_desc = 0; - uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + int32_t *BufLen; + int32_t len, max_len, alloc_length; + int pos = 0; + int idx = 0; + unsigned size_idx, preamble_len; + uint32_t last_sector = 0; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + int block_desc = 0; + uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_id & 0x0f; BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -587,8 +556,8 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) device_identify[6] = (dev->id / 10) + 0x30; device_identify[7] = (dev->id % 10) + 0x30; - device_identify_ex[6] = (dev->id / 10) + 0x30; - device_identify_ex[7] = (dev->id % 10) + 0x30; + device_identify_ex[6] = (dev->id / 10) + 0x30; + device_identify_ex[7] = (dev->id % 10) + 0x30; device_identify_ex[10] = EMU_VERSION_EX[0]; device_identify_ex[12] = EMU_VERSION_EX[2]; device_identify_ex[13] = EMU_VERSION_EX[3]; @@ -596,13 +565,13 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - scsi_disk_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", - dev->id, cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); - scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->request_length); + scsi_disk_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", + dev->id, cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); + scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->request_length); - scsi_disk_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); + scsi_disk_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + cdb[8], cdb[9], cdb[10], cdb[11]); } dev->sector_len = 0; @@ -611,458 +580,458 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ if (scsi_disk_pre_execution_check(dev, cdb) == 0) - return; + return; switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - scsi_disk_invalid_field(dev); - return; - } - /*FALLTHROUGH*/ - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - case GPCMD_FORMAT_UNIT: - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; + case GPCMD_SEND_DIAGNOSTIC: + if (!(cdb[1] & (1 << 2))) { + scsi_disk_invalid_field(dev); + return; + } + /*FALLTHROUGH*/ + case GPCMD_SCSI_RESERVE: + case GPCMD_SCSI_RELEASE: + case GPCMD_TEST_UNIT_READY: + case GPCMD_FORMAT_UNIT: + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); + break; - case GPCMD_REZERO_UNIT: - dev->sector_pos = dev->sector_len = 0; - scsi_disk_seek(dev, 0); - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - break; + case GPCMD_REZERO_UNIT: + dev->sector_pos = dev->sector_len = 0; + scsi_disk_seek(dev, 0); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + break; - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - len = cdb[4]; + case GPCMD_REQUEST_SENSE: + /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE + should forget about the not ready, and report unit attention straight away. */ + len = cdb[4]; - if (!len) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - break; - } + if (!len) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + break; + } - scsi_disk_buf_alloc(dev, 256); - scsi_disk_set_buf_len(dev, BufLen, &len); + scsi_disk_buf_alloc(dev, 256); + scsi_disk_set_buf_len(dev, BufLen, &len); - if (*BufLen < cdb[4]) - cdb[4] = *BufLen; + if (*BufLen < cdb[4]) + cdb[4] = *BufLen; - len = (cdb[1] & 1) ? 8 : 18; + len = (cdb[1] & 1) ? 8 : 18; - scsi_disk_request_sense(dev, dev->temp_buffer, *BufLen, cdb[1] & 1); - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, cdb[4], 0); - break; + scsi_disk_request_sense(dev, dev->temp_buffer, *BufLen, cdb[1] & 1); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, len, len, cdb[4], 0); + break; - case GPCMD_MECHANISM_STATUS: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - len = (cdb[8] << 8) | cdb[9]; + case GPCMD_MECHANISM_STATUS: + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + len = (cdb[8] << 8) | cdb[9]; - scsi_disk_buf_alloc(dev, 8); - scsi_disk_set_buf_len(dev, BufLen, &len); + scsi_disk_buf_alloc(dev, 8); + scsi_disk_set_buf_len(dev, BufLen, &len); - memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[5] = 1; + memset(dev->temp_buffer, 0, 8); + dev->temp_buffer[5] = 1; - scsi_disk_data_command_finish(dev, 8, 8, len, 0); - break; + scsi_disk_data_command_finish(dev, 8, 8, len, 0); + break; - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + switch (cdb[0]) { + case GPCMD_READ_6: + dev->sector_len = cdb[4]; + if (dev->sector_len == 0) + dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + break; + case GPCMD_READ_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + break; + case GPCMD_READ_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } - if ((dev->sector_pos > last_sector)/* || ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/) { - scsi_disk_lba_out_of_range(dev); - return; - } + if ((dev->sector_pos > last_sector) /* || ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/) { + scsi_disk_lba_out_of_range(dev); + return; + } - 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 = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - break; - } + 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 = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + break; + } - max_len = dev->sector_len; - dev->requested_blocks = max_len; + max_len = dev->sector_len; + dev->requested_blocks = max_len; - alloc_length = dev->packet_len = max_len << 9; - scsi_disk_buf_alloc(dev, dev->packet_len); - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + alloc_length = dev->packet_len = max_len << 9; + scsi_disk_buf_alloc(dev, dev->packet_len); + scsi_disk_set_buf_len(dev, BufLen, &alloc_length); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - if ((dev->requested_blocks > 0) && (*BufLen > 0)) { - if (dev->packet_len > (uint32_t) *BufLen) - hdd_image_read(dev->id, dev->sector_pos, *BufLen >> 9, dev->temp_buffer); - else - hdd_image_read(dev->id, dev->sector_pos, dev->requested_blocks, dev->temp_buffer); - } + if ((dev->requested_blocks > 0) && (*BufLen > 0)) { + if (dev->packet_len > (uint32_t) *BufLen) + hdd_image_read(dev->id, dev->sector_pos, *BufLen >> 9, dev->temp_buffer); + else + hdd_image_read(dev->id, dev->sector_pos, dev->requested_blocks, dev->temp_buffer); + } - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); + if (dev->requested_blocks > 1) + scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); + else + scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); - else - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); - return; + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); + else + ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); + return; - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - if (!(cdb[1] & 2)) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; - } - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - switch(cdb[0]) - { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - dev->sector_len = cdb[4]; - if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + if (!(cdb[1] & 2)) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); + break; + } + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + switch (cdb[0]) { + case GPCMD_VERIFY_6: + case GPCMD_WRITE_6: + dev->sector_len = cdb[4]; + if (dev->sector_len == 0) + dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_VERIFY_10: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_VERIFY_12: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } - if ((dev->sector_pos > last_sector)/* || - ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/) { - scsi_disk_lba_out_of_range(dev); - return; - } + if ((dev->sector_pos > last_sector) /* || + ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/ + ) { + scsi_disk_lba_out_of_range(dev); + return; + } - 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 = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - break; - } + 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 = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + break; + } - max_len = dev->sector_len; - dev->requested_blocks = max_len; + max_len = dev->sector_len; + dev->requested_blocks = max_len; - alloc_length = dev->packet_len = max_len << 9; - scsi_disk_buf_alloc(dev, dev->packet_len); + alloc_length = dev->packet_len = max_len << 9; + scsi_disk_buf_alloc(dev, dev->packet_len); - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + scsi_disk_set_buf_len(dev, BufLen, &alloc_length); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); + if (dev->requested_blocks > 1) + scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); + else + scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); - else - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); - return; + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); + else + ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); + return; - case GPCMD_WRITE_SAME_10: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - alloc_length = 512; + case GPCMD_WRITE_SAME_10: + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + alloc_length = 512; - if ((cdb[1] & 6) == 6) { - scsi_disk_invalid_field(dev); - return; - } + if ((cdb[1] & 6) == 6) { + scsi_disk_invalid_field(dev); + return; + } - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - if ((dev->sector_pos > last_sector)/* || - ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/) { - scsi_disk_lba_out_of_range(dev); - return; - } + if ((dev->sector_pos > last_sector) /* || + ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/ + ) { + scsi_disk_lba_out_of_range(dev); + return; + } - 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 = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - break; - } + 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 = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + break; + } - scsi_disk_buf_alloc(dev, alloc_length); - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); + scsi_disk_buf_alloc(dev, alloc_length); + scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - max_len = 1; - dev->requested_blocks = 1; + max_len = 1; + dev->requested_blocks = 1; - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - scsi_disk_data_command_finish(dev, 512, 512, alloc_length, 1); + scsi_disk_data_command_finish(dev, 512, 512, alloc_length, 1); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); - else - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); - return; + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); + else + ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); + return; - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - scsi_disk_buf_alloc(dev, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - scsi_disk_buf_alloc(dev, 65536); - } + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = cdb[4]; + scsi_disk_buf_alloc(dev, 256); + } else { + len = (cdb[8] | (cdb[7] << 8)); + scsi_disk_buf_alloc(dev, 65536); + } - memset(dev->temp_buffer, 0, len); - alloc_length = len; + memset(dev->temp_buffer, 0, len); + alloc_length = len; - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_disk_mode_sense(dev, dev->temp_buffer, 4, cdb[2], block_desc); - if (len > alloc_length) - len = alloc_length; - dev->temp_buffer[0] = len - 1; - dev->temp_buffer[1] = 0; - if (block_desc) - dev->temp_buffer[3] = 8; - } else { - len = scsi_disk_mode_sense(dev, dev->temp_buffer, 8, cdb[2], block_desc); - if (len > alloc_length) - len = alloc_length; - dev->temp_buffer[0] = (len - 2) >> 8; - dev->temp_buffer[1] = (len - 2) & 255; - dev->temp_buffer[2] = 0; - if (block_desc) { - dev->temp_buffer[6] = 0; - dev->temp_buffer[7] = 8; - } - } + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = scsi_disk_mode_sense(dev, dev->temp_buffer, 4, cdb[2], block_desc); + if (len > alloc_length) + len = alloc_length; + dev->temp_buffer[0] = len - 1; + dev->temp_buffer[1] = 0; + if (block_desc) + dev->temp_buffer[3] = 8; + } else { + len = scsi_disk_mode_sense(dev, dev->temp_buffer, 8, cdb[2], block_desc); + if (len > alloc_length) + len = alloc_length; + dev->temp_buffer[0] = (len - 2) >> 8; + dev->temp_buffer[1] = (len - 2) & 255; + dev->temp_buffer[2] = 0; + if (block_desc) { + dev->temp_buffer[6] = 0; + dev->temp_buffer[7] = 8; + } + } - if (len > alloc_length) - len = alloc_length; - else if (len < alloc_length) - alloc_length = len; + if (len > alloc_length) + len = alloc_length; + else if (len < alloc_length) + alloc_length = len; - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - scsi_disk_log("SCSI HDD %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + scsi_disk_set_buf_len(dev, BufLen, &alloc_length); + scsi_disk_log("SCSI HDD %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - scsi_disk_data_command_finish(dev, len, len, alloc_length, 0); - return; + scsi_disk_data_command_finish(dev, len, len, alloc_length, 0); + return; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - scsi_disk_buf_alloc(dev, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - scsi_disk_buf_alloc(dev, 65536); - } + if (cdb[0] == GPCMD_MODE_SELECT_6) { + len = cdb[4]; + scsi_disk_buf_alloc(dev, 256); + } else { + len = (cdb[7] << 8) | cdb[8]; + scsi_disk_buf_alloc(dev, 65536); + } - scsi_disk_set_buf_len(dev, BufLen, &len); - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - scsi_disk_data_command_finish(dev, len, len, len, 1); - return; + scsi_disk_set_buf_len(dev, BufLen, &len); + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; + scsi_disk_data_command_finish(dev, len, len, len, 1); + return; - case GPCMD_INQUIRY: - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; + case GPCMD_INQUIRY: + max_len = cdb[3]; + max_len <<= 8; + max_len |= cdb[4]; - 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 = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - break; - } + 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 = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + break; + } - scsi_disk_buf_alloc(dev, 65536); + scsi_disk_buf_alloc(dev, 65536); - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; + if (cdb[1] & 1) { + preamble_len = 4; + size_idx = 3; - dev->temp_buffer[idx++] = 05; - dev->temp_buffer[idx++] = cdb[2]; - dev->temp_buffer[idx++] = 0; + dev->temp_buffer[idx++] = 05; + dev->temp_buffer[idx++] = cdb[2]; + dev->temp_buffer[idx++] = 0; - idx++; + idx++; - switch (cdb[2]) { - case 0x00: - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - scsi_disk_buf_free(dev); - scsi_disk_data_phase_error(dev); - return; - } + switch (cdb[2]) { + case 0x00: + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 0x83; + break; + case 0x83: + if (idx + 24 > max_len) { + scsi_disk_buf_free(dev); + scsi_disk_data_phase_error(dev); + return; + } - dev->temp_buffer[idx++] = 0x02; - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 20; - ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Serial */ - idx += 20; + dev->temp_buffer[idx++] = 0x02; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 20; + ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Serial */ + idx += 20; - if (idx + 72 > cdb[4]) - goto atapi_out; - dev->temp_buffer[idx++] = 0x02; - dev->temp_buffer[idx++] = 0x01; - dev->temp_buffer[idx++] = 0x00; - dev->temp_buffer[idx++] = 68; - ide_padstr8(dev->temp_buffer + idx, 8, EMU_NAME); /* Vendor */ - idx += 8; - ide_padstr8(dev->temp_buffer + idx, 40, device_identify_ex); /* Product */ - idx += 40; - ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - scsi_disk_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - scsi_disk_invalid_field(dev); - scsi_disk_buf_free(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; + if (idx + 72 > cdb[4]) + goto atapi_out; + dev->temp_buffer[idx++] = 0x02; + dev->temp_buffer[idx++] = 0x01; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 68; + ide_padstr8(dev->temp_buffer + idx, 8, EMU_NAME); /* Vendor */ + idx += 8; + ide_padstr8(dev->temp_buffer + idx, 40, device_identify_ex); /* Product */ + idx += 40; + ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Product */ + idx += 20; + break; + default: + scsi_disk_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + scsi_disk_invalid_field(dev); + scsi_disk_buf_free(dev); + return; + } + } else { + preamble_len = 5; + size_idx = 4; - memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = 0; /*SCSI HD*/ - dev->temp_buffer[1] = 0; /*Fixed*/ - dev->temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ - dev->temp_buffer[3] = 0x02; - dev->temp_buffer[4] = 31; - dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ - dev->temp_buffer[7] = 0x20; /* Wide bus supported */ + memset(dev->temp_buffer, 0, 8); + dev->temp_buffer[0] = 0; /*SCSI HD*/ + dev->temp_buffer[1] = 0; /*Fixed*/ + dev->temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ + dev->temp_buffer[3] = 0x02; + dev->temp_buffer[4] = 31; + dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ + dev->temp_buffer[7] = 0x20; /* Wide bus supported */ - ide_padstr8(dev->temp_buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->temp_buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->temp_buffer + 32, 4, EMU_VERSION_EX); /* Revision */ - idx = 36; + ide_padstr8(dev->temp_buffer + 8, 8, EMU_NAME); /* Vendor */ + ide_padstr8(dev->temp_buffer + 16, 16, device_identify); /* Product */ + ide_padstr8(dev->temp_buffer + 32, 4, EMU_VERSION_EX); /* Revision */ + idx = 36; - if (max_len == 96) { - dev->temp_buffer[4] = 91; - idx = 96; - } - } + if (max_len == 96) { + dev->temp_buffer[4] = 91; + idx = 96; + } + } atapi_out: - dev->temp_buffer[size_idx] = idx - preamble_len; - len=idx; + dev->temp_buffer[size_idx] = idx - preamble_len; + len = idx; - if (len > max_len) - len = max_len; + if (len > max_len) + len = max_len; - scsi_disk_set_buf_len(dev, BufLen, &len); + scsi_disk_set_buf_len(dev, BufLen, &len); - if (len > *BufLen) - len = *BufLen; + if (len > *BufLen) + len = *BufLen; - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, max_len, 0); - break; + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, len, len, max_len, 0); + break; - case GPCMD_PREVENT_REMOVAL: - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; + case GPCMD_PREVENT_REMOVAL: + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); + break; - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; - break; - } - scsi_disk_seek(dev, pos); + case GPCMD_SEEK_6: + case GPCMD_SEEK_10: + switch (cdb[0]) { + case GPCMD_SEEK_6: + pos = (cdb[2] << 8) | cdb[3]; + break; + case GPCMD_SEEK_10: + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + break; + } + scsi_disk_seek(dev, pos); - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_command_complete(dev); - break; + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); + break; - case GPCMD_READ_CDROM_CAPACITY: - scsi_disk_buf_alloc(dev, 8); + case GPCMD_READ_CDROM_CAPACITY: + scsi_disk_buf_alloc(dev, 8); - max_len = hdd_image_get_last_sector(dev->id); - memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = (max_len >> 24) & 0xff; - dev->temp_buffer[1] = (max_len >> 16) & 0xff; - dev->temp_buffer[2] = (max_len >> 8) & 0xff; - dev->temp_buffer[3] = max_len & 0xff; - dev->temp_buffer[6] = 2; - len = 8; + max_len = hdd_image_get_last_sector(dev->id); + memset(dev->temp_buffer, 0, 8); + dev->temp_buffer[0] = (max_len >> 24) & 0xff; + dev->temp_buffer[1] = (max_len >> 16) & 0xff; + dev->temp_buffer[2] = (max_len >> 8) & 0xff; + dev->temp_buffer[3] = max_len & 0xff; + dev->temp_buffer[6] = 2; + len = 8; - scsi_disk_set_buf_len(dev, BufLen, &len); + scsi_disk_set_buf_len(dev, BufLen, &len); - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, len, 0); - break; + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, len, len, len, 0); + break; - default: - scsi_disk_illegal_opcode(dev); - break; + default: + scsi_disk_illegal_opcode(dev); + break; } /* scsi_disk_log("SCSI HD %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ } - static void scsi_disk_command_stop(scsi_common_t *sc) { @@ -1072,233 +1041,230 @@ scsi_disk_command_stop(scsi_common_t *sc) scsi_disk_buf_free(dev); } - static uint8_t scsi_disk_phase_data_out(scsi_common_t *sc) { - scsi_disk_t *dev = (scsi_disk_t *) sc; - uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; - int i; - int32_t *BufLen = &scsi_devices[scsi_bus][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; - uint16_t param_list_len; - uint8_t hdr_len, val, old_val, ch, error = 0; - uint8_t page, page_len; + scsi_disk_t *dev = (scsi_disk_t *) sc; + uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + int i; + int32_t *BufLen = &scsi_devices[scsi_bus][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; + uint16_t param_list_len; + uint8_t hdr_len, val, old_val, ch, error = 0; + uint8_t page, page_len; if (!*BufLen) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - return 1; + return 1; } switch (dev->current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if ((dev->requested_blocks > 0) && (*BufLen > 0)) { - if (dev->packet_len > (uint32_t) *BufLen) - hdd_image_write(dev->id, dev->sector_pos, *BufLen >> 9, dev->temp_buffer); - else - hdd_image_write(dev->id, dev->sector_pos, dev->requested_blocks, dev->temp_buffer); - } - break; - case GPCMD_WRITE_SAME_10: - if (!dev->current_cdb[7] && !dev->current_cdb[8]) - last_to_write = last_sector; - else - last_to_write = dev->sector_pos + dev->sector_len - 1; + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + break; + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + if ((dev->requested_blocks > 0) && (*BufLen > 0)) { + if (dev->packet_len > (uint32_t) *BufLen) + hdd_image_write(dev->id, dev->sector_pos, *BufLen >> 9, dev->temp_buffer); + else + hdd_image_write(dev->id, dev->sector_pos, dev->requested_blocks, dev->temp_buffer); + } + break; + case GPCMD_WRITE_SAME_10: + if (!dev->current_cdb[7] && !dev->current_cdb[8]) + last_to_write = last_sector; + else + last_to_write = dev->sector_pos + dev->sector_len - 1; - for (i = dev->sector_pos; i <= (int) last_to_write; i++) { - if (dev->current_cdb[1] & 2) { - dev->temp_buffer[0] = (i >> 24) & 0xff; - dev->temp_buffer[1] = (i >> 16) & 0xff; - dev->temp_buffer[2] = (i >> 8) & 0xff; - dev->temp_buffer[3] = i & 0xff; - } else if (dev->current_cdb[1] & 4) { - s = (i % dev->drv->spt); - h = ((i - s) / dev->drv->spt) % dev->drv->hpc; - c = ((i - s) / dev->drv->spt) / dev->drv->hpc; - dev->temp_buffer[0] = (c >> 16) & 0xff; - dev->temp_buffer[1] = (c >> 8) & 0xff; - dev->temp_buffer[2] = c & 0xff; - dev->temp_buffer[3] = h & 0xff; - dev->temp_buffer[4] = (s >> 24) & 0xff; - dev->temp_buffer[5] = (s >> 16) & 0xff; - dev->temp_buffer[6] = (s >> 8) & 0xff; - dev->temp_buffer[7] = s & 0xff; - } - hdd_image_write(dev->id, i, 1, dev->temp_buffer); - } - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { - hdr_len = 8; - param_list_len = dev->current_cdb[7]; - param_list_len <<= 8; - param_list_len |= dev->current_cdb[8]; - } else { - hdr_len = 4; - param_list_len = dev->current_cdb[4]; - } + for (i = dev->sector_pos; i <= (int) last_to_write; i++) { + if (dev->current_cdb[1] & 2) { + dev->temp_buffer[0] = (i >> 24) & 0xff; + dev->temp_buffer[1] = (i >> 16) & 0xff; + dev->temp_buffer[2] = (i >> 8) & 0xff; + dev->temp_buffer[3] = i & 0xff; + } else if (dev->current_cdb[1] & 4) { + s = (i % dev->drv->spt); + h = ((i - s) / dev->drv->spt) % dev->drv->hpc; + c = ((i - s) / dev->drv->spt) / dev->drv->hpc; + dev->temp_buffer[0] = (c >> 16) & 0xff; + dev->temp_buffer[1] = (c >> 8) & 0xff; + dev->temp_buffer[2] = c & 0xff; + dev->temp_buffer[3] = h & 0xff; + dev->temp_buffer[4] = (s >> 24) & 0xff; + dev->temp_buffer[5] = (s >> 16) & 0xff; + dev->temp_buffer[6] = (s >> 8) & 0xff; + dev->temp_buffer[7] = s & 0xff; + } + hdd_image_write(dev->id, i, 1, dev->temp_buffer); + } + break; + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { + hdr_len = 8; + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { + hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = dev->temp_buffer[2]; - block_desc_len <<= 8; - block_desc_len |= dev->temp_buffer[3]; - } else { - block_desc_len = dev->temp_buffer[6]; - block_desc_len <<= 8; - block_desc_len |= dev->temp_buffer[7]; - } + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = dev->temp_buffer[2]; + block_desc_len <<= 8; + block_desc_len |= dev->temp_buffer[3]; + } else { + block_desc_len = dev->temp_buffer[6]; + block_desc_len <<= 8; + block_desc_len |= dev->temp_buffer[7]; + } - pos = hdr_len + block_desc_len; + pos = hdr_len + block_desc_len; - while(1) { - if (pos >= param_list_len) { - scsi_disk_log("SCSI HD %i: Buffer has only block descriptor\n", dev->id); - break; - } + while (1) { + if (pos >= param_list_len) { + scsi_disk_log("SCSI HD %i: Buffer has only block descriptor\n", dev->id); + break; + } - page = dev->temp_buffer[pos] & 0x3F; - page_len = dev->temp_buffer[pos + 1]; + page = dev->temp_buffer[pos] & 0x3F; + page_len = dev->temp_buffer[pos + 1]; - pos += 2; + pos += 2; - if (!(scsi_disk_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = scsi_disk_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->temp_buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; - } - } - } + if (!(scsi_disk_mode_sense_page_flags & (1LL << ((uint64_t) page)))) + error |= 1; + else { + for (i = 0; i < page_len; i++) { + ch = scsi_disk_mode_sense_pages_changeable.pages[page][i + 2]; + val = dev->temp_buffer[pos + i]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else + error |= 1; + } + } + } - pos += page_len; + pos += page_len; - val = scsi_disk_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - scsi_disk_mode_sense_save(dev); + val = scsi_disk_mode_sense_pages_default.pages[page][0] & 0x80; + if (dev->do_page_save && val) + scsi_disk_mode_sense_save(dev); - if (pos >= dev->total_length) - break; - } + if (pos >= dev->total_length) + break; + } - if (error) { - scsi_disk_buf_free(dev); - scsi_disk_invalid_field_pl(dev); - } - break; - default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); - break; + if (error) { + scsi_disk_buf_free(dev); + scsi_disk_invalid_field_pl(dev); + } + break; + default: + fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); + break; } scsi_disk_command_stop((scsi_common_t *) dev); return 1; } - void scsi_disk_hard_reset(void) { - int c; - scsi_disk_t *dev; + int c; + scsi_disk_t *dev; scsi_device_t *sd; - uint8_t scsi_bus, scsi_id; + uint8_t scsi_bus, scsi_id; 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); + if (hdd[c].bus == HDD_BUS_SCSI) { + scsi_disk_log("SCSI disk hard_reset drive=%d\n", c); - scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; - scsi_id = hdd[c].scsi_id & 0x0f; + scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; + scsi_id = hdd[c].scsi_id & 0x0f; - /* Make sure to ignore any SCSI disk that has an out of range SCSI bus. */ - if (scsi_bus >= SCSI_BUS_MAX) - continue; + /* Make sure to ignore any SCSI disk that has an out of range SCSI bus. */ + if (scsi_bus >= SCSI_BUS_MAX) + continue; - /* Make sure to ignore any SCSI disk that has an out of range ID. */ - if (scsi_id >= SCSI_ID_MAX) - continue; + /* Make sure to ignore any SCSI disk that has an out of range ID. */ + if (scsi_id >= SCSI_ID_MAX) + continue; - /* Make sure to ignore any SCSI disk whose image file name is empty. */ - if (strlen(hdd[c].fn) == 0) - continue; + /* Make sure to ignore any SCSI disk whose image file name is empty. */ + if (strlen(hdd[c].fn) == 0) + continue; - /* Make sure to ignore any SCSI disk whose image fails to load. */ - if (! hdd_image_load(c)) - continue; + /* Make sure to ignore any SCSI disk whose image fails to load. */ + if (!hdd_image_load(c)) + continue; - if (!hdd[c].priv) { - hdd[c].priv = (scsi_disk_t *) malloc(sizeof(scsi_disk_t)); - memset(hdd[c].priv, 0, sizeof(scsi_disk_t)); - } + if (!hdd[c].priv) { + hdd[c].priv = (scsi_disk_t *) malloc(sizeof(scsi_disk_t)); + memset(hdd[c].priv, 0, sizeof(scsi_disk_t)); + } - dev = (scsi_disk_t *) hdd[c].priv; + dev = (scsi_disk_t *) hdd[c].priv; - /* SCSI disk, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + /* SCSI disk, attach to the SCSI bus. */ + sd = &scsi_devices[scsi_bus][scsi_id]; - sd->sc = (scsi_common_t *) dev; - sd->command = scsi_disk_command; - sd->request_sense = scsi_disk_request_sense_for_scsi; - sd->reset = scsi_disk_reset; - sd->phase_data_out = scsi_disk_phase_data_out; - sd->command_stop = scsi_disk_command_stop; - sd->type = SCSI_FIXED_DISK; + sd->sc = (scsi_common_t *) dev; + sd->command = scsi_disk_command; + sd->request_sense = scsi_disk_request_sense_for_scsi; + sd->reset = scsi_disk_reset; + sd->phase_data_out = scsi_disk_phase_data_out; + sd->command_stop = scsi_disk_command_stop; + sd->type = SCSI_FIXED_DISK; - dev->id = c; - dev->drv = &hdd[c]; + dev->id = c; + dev->drv = &hdd[c]; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->cur_lun = SCSI_LUN_USE_CDB; - scsi_disk_mode_sense_load(dev); + scsi_disk_mode_sense_load(dev); - scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); - } + scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); + } } } - void scsi_disk_close(void) { scsi_disk_t *dev; - int c; - uint8_t scsi_bus, scsi_id; + int c; + uint8_t scsi_bus, scsi_id; for (c = 0; c < HDD_NUM; c++) { - if (hdd[c].bus == HDD_BUS_SCSI) { - scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; - scsi_id = hdd[c].scsi_id & 0x0f; + if (hdd[c].bus == HDD_BUS_SCSI) { + scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; + scsi_id = hdd[c].scsi_id & 0x0f; - memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); + memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); - hdd_image_close(c); + hdd_image_close(c); - dev = hdd[c].priv; + dev = hdd[c].priv; - if (dev) { - free(dev); - hdd[c].priv = NULL; - } - } + if (dev) { + free(dev); + hdd[c].priv = NULL; + } + } } } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 387d650f1..b022d59dd 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -42,160 +42,155 @@ #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" +#define RT1000B_810R_ROM "roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" +#define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" +#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" +#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" +#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" -#define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" -#define RT1000B_810R_ROM "roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" -#define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" -#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" -#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" +#define NCR_CURDATA 0 /* current SCSI data (read only) */ +#define NCR_OUTDATA 0 /* output data (write only) */ +#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ +#define NCR_MODE 2 /* mode (read/write) */ +#define NCR_TARGETCMD 3 /* target command (read/write) */ +#define NCR_SELENABLE 4 /* select enable (write only) */ +#define NCR_BUSSTATUS 4 /* bus status (read only) */ +#define NCR_STARTDMA 5 /* start DMA send (write only) */ +#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ +#define NCR_DMATARGET 6 /* DMA target (write only) */ +#define NCR_INPUTDATA 6 /* input data (read only) */ +#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ +#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ +#define ICR_DBP 0x01 +#define ICR_ATN 0x02 +#define ICR_SEL 0x04 +#define ICR_BSY 0x08 +#define ICR_ACK 0x10 +#define ICR_ARB_LOST 0x20 +#define ICR_ARB_IN_PROGRESS 0x40 -#define NCR_CURDATA 0 /* current SCSI data (read only) */ -#define NCR_OUTDATA 0 /* output data (write only) */ -#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ -#define NCR_MODE 2 /* mode (read/write) */ -#define NCR_TARGETCMD 3 /* target command (read/write) */ -#define NCR_SELENABLE 4 /* select enable (write only) */ -#define NCR_BUSSTATUS 4 /* bus status (read only) */ -#define NCR_STARTDMA 5 /* start DMA send (write only) */ -#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ -#define NCR_DMATARGET 6 /* DMA target (write only) */ -#define NCR_INPUTDATA 6 /* input data (read only) */ -#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ -#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ +#define MODE_ARBITRATE 0x01 +#define MODE_DMA 0x02 +#define MODE_MONITOR_BUSY 0x04 +#define MODE_ENA_EOP_INT 0x08 -#define ICR_DBP 0x01 -#define ICR_ATN 0x02 -#define ICR_SEL 0x04 -#define ICR_BSY 0x08 -#define ICR_ACK 0x10 -#define ICR_ARB_LOST 0x20 -#define ICR_ARB_IN_PROGRESS 0x40 +#define STATUS_ACK 0x01 +#define STATUS_BUSY_ERROR 0x04 +#define STATUS_PHASE_MATCH 0x08 +#define STATUS_INT 0x10 +#define STATUS_DRQ 0x40 +#define STATUS_END_OF_DMA 0x80 -#define MODE_ARBITRATE 0x01 -#define MODE_DMA 0x02 -#define MODE_MONITOR_BUSY 0x04 -#define MODE_ENA_EOP_INT 0x08 +#define TCR_IO 0x01 +#define TCR_CD 0x02 +#define TCR_MSG 0x04 +#define TCR_REQ 0x08 +#define TCR_LAST_BYTE_SENT 0x80 -#define STATUS_ACK 0x01 -#define STATUS_BUSY_ERROR 0x04 -#define STATUS_PHASE_MATCH 0x08 -#define STATUS_INT 0x10 -#define STATUS_DRQ 0x40 -#define STATUS_END_OF_DMA 0x80 - -#define TCR_IO 0x01 -#define TCR_CD 0x02 -#define TCR_MSG 0x04 -#define TCR_REQ 0x08 -#define TCR_LAST_BYTE_SENT 0x80 - -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 #define STATUS_53C80_ACCESSIBLE 0x80 typedef struct { - uint8_t icr, mode, tcr, data_wait; - uint8_t isr, output_data, target_id, tx_data; - uint8_t msglun; + uint8_t icr, mode, tcr, data_wait; + uint8_t isr, output_data, target_id, tx_data; + uint8_t msglun; - uint8_t command[20]; - uint8_t msgout[4]; - int msgout_pos; - int is_msgout; + uint8_t command[20]; + uint8_t msgout[4]; + int msgout_pos; + int is_msgout; - int dma_mode, cur_bus, bus_in, new_phase; - int state, clear_req, wait_data, wait_complete; - int command_pos, data_pos; + int dma_mode, cur_bus, bus_in, new_phase; + int state, clear_req, wait_data, wait_complete; + int command_pos, data_pos; } ncr_t; typedef struct { - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; + uint8_t ctrl; + uint8_t status; + uint8_t buffer[512]; + uint8_t ext_ram[0x80]; + uint8_t block_count; - int block_loaded; - int pos, host_pos; + int block_loaded; + int pos, host_pos; - int bios_enabled; + int bios_enabled; } t128_t; typedef struct { - ncr_t ncr; - t128_t t128; + ncr_t ncr; + t128_t t128; - const char *name; + const char *name; - uint8_t buffer[128]; - uint8_t int_ram[0x40], ext_ram[0x600]; + uint8_t buffer[128]; + uint8_t int_ram[0x40], ext_ram[0x600]; - uint32_t rom_addr; - uint16_t base; + uint32_t rom_addr; + uint16_t base; - int8_t irq; - int8_t type; - int8_t bios_ver; - uint8_t block_count; - uint8_t status_ctrl; - uint8_t bus, pad; + int8_t irq; + int8_t type; + int8_t bios_ver; + uint8_t block_count; + uint8_t status_ctrl; + uint8_t bus, pad; - rom_t bios_rom; + rom_t bios_rom; mem_mapping_t mapping; - int block_count_loaded; + int block_count_loaded; - int buffer_pos; - int buffer_host_pos; + int buffer_pos; + int buffer_host_pos; - int dma_enabled; + int dma_enabled; - pc_timer_t timer; - double period; + pc_timer_t timer; + double period; - int ncr_busy; + int ncr_busy; uint8_t pos_regs[8]; } ncr5380_t; -#define STATE_IDLE 0 -#define STATE_COMMAND 1 -#define STATE_DATAIN 2 -#define STATE_DATAOUT 3 -#define STATE_STATUS 4 -#define STATE_MESSAGEIN 5 -#define STATE_SELECT 6 -#define STATE_MESSAGEOUT 7 -#define STATE_MESSAGE_ID 8 +#define STATE_IDLE 0 +#define STATE_COMMAND 1 +#define STATE_DATAIN 2 +#define STATE_DATAOUT 3 +#define STATE_STATUS 4 +#define STATE_MESSAGEIN 5 +#define STATE_SELECT 6 +#define STATE_MESSAGEOUT 7 +#define STATE_MESSAGE_ID 8 -#define DMA_IDLE 0 -#define DMA_SEND 1 +#define DMA_IDLE 0 +#define DMA_SEND 1 #define DMA_INITIATOR_RECEIVE 2 -static int cmd_len[8] = {6, 10, 10, 6, 16, 12, 6, 6}; - +static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 6, 6 }; #ifdef ENABLE_NCR5380_LOG int ncr5380_do_log = ENABLE_NCR5380_LOG; - static void ncr_log(const char *fmt, ...) { va_list ap; if (ncr5380_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ncr_log(fmt, ...) +# define ncr_log(fmt, ...) #endif - #define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) static void @@ -211,11 +206,11 @@ static void ncr_irq(ncr5380_t *ncr_dev, ncr_t *ncr, int set_irq) { if (set_irq) { - ncr->isr |= STATUS_INT; - picint(1 << ncr_dev->irq); + ncr->isr |= STATUS_INT; + picint(1 << ncr_dev->irq); } else { - ncr->isr &= ~STATUS_INT; - picintc(1 << ncr_dev->irq); + ncr->isr &= ~STATUS_INT; + picintc(1 << ncr_dev->irq); } } @@ -225,23 +220,24 @@ get_dev_id(uint8_t data) int c; for (c = 0; c < SCSI_ID_MAX; c++) { - if (data & (1 << c)) return(c); + if (data & (1 << c)) + return (c); } - return(-1); + return (-1); } static int getmsglen(uint8_t *msgp, int len) { - uint8_t msg = msgp[0]; - if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) ||msg >= 0x80) - return 1; - if (msg >= 0x20 && msg <= 0x2f) - return 2; - if (len < 2) - return 3; - return msgp[1]; + uint8_t msg = msgp[0]; + if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) || msg >= 0x80) + return 1; + if (msg >= 0x20 && msg <= 0x2f) + return 2; + if (len < 2) + return 3; + return msgp[1]; } static void @@ -253,7 +249,7 @@ ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) timer_stop(&ncr_dev->timer); for (int i = 0; i < 8; i++) - scsi_device_reset(&scsi_devices[ncr_dev->bus][i]); + scsi_device_reset(&scsi_devices[ncr_dev->bus][i]); ncr_irq(ncr_dev, ncr, 0); } @@ -264,907 +260,917 @@ ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback) double p = ncr_dev->period; if (ncr->data_wait & 2) - ncr->data_wait &= ~2; + ncr->data_wait &= ~2; - if (callback) { - if (ncr_dev->type == 3) - p *= 512.0; - else - p *= 128.0; - } + if (callback) { + if (ncr_dev->type == 3) + p *= 512.0; + else + p *= 128.0; + } - p += 1.0; + p += 1.0; - ncr_log("P = %lf, command = %02x, callback = %i, period = %lf, t128 pos = %i\n", p, ncr->command[0], callback, ncr_dev->period, ncr_dev->t128.host_pos); - timer_on_auto(&ncr_dev->timer, p); + ncr_log("P = %lf, command = %02x, callback = %i, period = %lf, t128 pos = %i\n", p, ncr->command[0], callback, ncr_dev->period, ncr_dev->t128.host_pos); + timer_on_auto(&ncr_dev->timer, p); } - static uint32_t get_bus_host(ncr_t *ncr) { uint32_t bus_host = 0; if (ncr->icr & ICR_DBP) - bus_host |= BUS_DBP; + bus_host |= BUS_DBP; if (ncr->icr & ICR_SEL) - bus_host |= BUS_SEL; + bus_host |= BUS_SEL; if (ncr->tcr & TCR_IO) - bus_host |= BUS_IO; + bus_host |= BUS_IO; if (ncr->tcr & TCR_CD) - bus_host |= BUS_CD; + bus_host |= BUS_CD; if (ncr->tcr & TCR_MSG) - bus_host |= BUS_MSG; + bus_host |= BUS_MSG; if (ncr->tcr & TCR_REQ) - bus_host |= BUS_REQ; + bus_host |= BUS_REQ; if (ncr->icr & ICR_BSY) - bus_host |= BUS_BSY; + bus_host |= BUS_BSY; if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; + bus_host |= BUS_ATN; if (ncr->icr & ICR_ACK) - bus_host |= BUS_ACK; + bus_host |= BUS_ACK; if (ncr->mode & MODE_ARBITRATE) - bus_host |= BUS_ARB; + bus_host |= BUS_ARB; - return(bus_host | BUS_SETDATA(ncr->output_data)); + return (bus_host | BUS_SETDATA(ncr->output_data)); } - static void ncr_bus_read(ncr5380_t *ncr_dev) { - ncr_t *ncr = &ncr_dev->ncr; + ncr_t *ncr = &ncr_dev->ncr; scsi_device_t *dev; - int phase; + int phase; /*Wait processes to handle bus requests*/ if (ncr->clear_req) { - ncr->clear_req--; - if (!ncr->clear_req) { - ncr_log("Prelude to command data\n"); - SET_BUS_STATE(ncr, ncr->new_phase); - ncr->cur_bus |= BUS_REQ; - } + ncr->clear_req--; + if (!ncr->clear_req) { + ncr_log("Prelude to command data\n"); + SET_BUS_STATE(ncr, ncr->new_phase); + ncr->cur_bus |= BUS_REQ; + } } if (ncr->wait_data) { - ncr->wait_data--; - if (!ncr->wait_data) { - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - SET_BUS_STATE(ncr, ncr->new_phase); - phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN); + ncr->wait_data--; + if (!ncr->wait_data) { + dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + SET_BUS_STATE(ncr, ncr->new_phase); + phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN); - if (phase == SCSI_PHASE_DATA_IN) { - ncr->tx_data = dev->sc->temp_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 (phase == SCSI_PHASE_DATA_OUT) { - if (ncr->new_phase & BUS_IDLE) { - ncr->state = STATE_IDLE; - ncr->cur_bus &= ~BUS_BSY; - } else - ncr->state = STATE_DATAOUT; - } else if (phase == SCSI_PHASE_STATUS) { - ncr->cur_bus |= BUS_REQ; - ncr->state = STATE_STATUS; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP; - } else if (phase == SCSI_PHASE_MESSAGE_IN) { - ncr->state = STATE_MESSAGEIN; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; - } else if (phase == SCSI_PHASE_MESSAGE_OUT) { - ncr->cur_bus |= BUS_REQ; - ncr->state = STATE_MESSAGEOUT; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->target_id >> 5) | BUS_DBP; - } - } + if (phase == SCSI_PHASE_DATA_IN) { + ncr->tx_data = dev->sc->temp_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 (phase == SCSI_PHASE_DATA_OUT) { + if (ncr->new_phase & BUS_IDLE) { + ncr->state = STATE_IDLE; + ncr->cur_bus &= ~BUS_BSY; + } else + ncr->state = STATE_DATAOUT; + } else if (phase == SCSI_PHASE_STATUS) { + ncr->cur_bus |= BUS_REQ; + ncr->state = STATE_STATUS; + ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP; + } else if (phase == SCSI_PHASE_MESSAGE_IN) { + ncr->state = STATE_MESSAGEIN; + ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; + } else if (phase == SCSI_PHASE_MESSAGE_OUT) { + ncr->cur_bus |= BUS_REQ; + ncr->state = STATE_MESSAGEOUT; + ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->target_id >> 5) | BUS_DBP; + } + } } if (ncr->wait_complete) { - ncr->wait_complete--; - if (!ncr->wait_complete) - ncr->cur_bus |= BUS_REQ; + ncr->wait_complete--; + if (!ncr->wait_complete) + ncr->cur_bus |= BUS_REQ; } } - static void ncr_bus_update(void *priv, int bus) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - double p; - uint8_t sel_data; - int msglen; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + double p; + uint8_t sel_data; + int msglen; /*Start the SCSI command layer, which will also make the timings*/ if (bus & BUS_ARB) - ncr->state = STATE_IDLE; + ncr->state = STATE_IDLE; ncr_log("State = %i\n", ncr->state); switch (ncr->state) { - case STATE_IDLE: - ncr->clear_req = ncr->wait_data = ncr->wait_complete = 0; - if ((bus & BUS_SEL) && !(bus & BUS_BSY)) { - ncr_log("Selection phase\n"); - sel_data = BUS_GETDATA(bus); + case STATE_IDLE: + ncr->clear_req = ncr->wait_data = ncr->wait_complete = 0; + if ((bus & BUS_SEL) && !(bus & BUS_BSY)) { + ncr_log("Selection phase\n"); + sel_data = BUS_GETDATA(bus); - ncr->target_id = get_dev_id(sel_data); + ncr->target_id = get_dev_id(sel_data); - ncr_log("Select - target ID = %i\n", ncr->target_id); + 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 != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr->cur_bus |= BUS_BSY; - ncr->state = STATE_SELECT; - } else { - ncr_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - ncr->cur_bus = 0; - } - } - break; - case STATE_SELECT: - if (!(bus & BUS_SEL)) { - if (!(bus & BUS_ATN)) { - if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - ncr->state = STATE_COMMAND; - ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); - ncr->command_pos = 0; - SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); - } else { - ncr->state = STATE_IDLE; - ncr->cur_bus = 0; - } - } else { - ncr_log("Set to SCSI Message Out\n"); - ncr->new_phase = SCSI_PHASE_MESSAGE_OUT; - ncr->wait_data = 4; - ncr->msgout_pos = 0; - ncr->is_msgout = 1; - } - } - break; - case STATE_COMMAND: - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - /*Write command byte to the output data register*/ - ncr->command[ncr->command_pos++] = BUS_GETDATA(bus); - ncr->clear_req = 3; - ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; - ncr->cur_bus &= ~BUS_REQ; + /*Once the device has been found and selected, mark it as busy*/ + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { + ncr->cur_bus |= BUS_BSY; + ncr->state = STATE_SELECT; + } else { + ncr_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + ncr->cur_bus = 0; + } + } + break; + case STATE_SELECT: + if (!(bus & BUS_SEL)) { + if (!(bus & BUS_ATN)) { + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { + ncr_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + ncr->state = STATE_COMMAND; + ncr->cur_bus = BUS_BSY | BUS_REQ; + ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); + ncr->command_pos = 0; + SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); + } else { + ncr->state = STATE_IDLE; + ncr->cur_bus = 0; + } + } else { + ncr_log("Set to SCSI Message Out\n"); + ncr->new_phase = SCSI_PHASE_MESSAGE_OUT; + ncr->wait_data = 4; + ncr->msgout_pos = 0; + ncr->is_msgout = 1; + } + } + break; + case STATE_COMMAND: + if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { + /*Write command byte to the output data register*/ + ncr->command[ncr->command_pos++] = BUS_GETDATA(bus); + ncr->clear_req = 3; + ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; + ncr->cur_bus &= ~BUS_REQ; - ncr_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); + ncr_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); - if (ncr->command_pos == cmd_len[(ncr->command[0] >> 5) & 7]) { - if (ncr->is_msgout) { - ncr->is_msgout = 0; - // ncr->command[1] = (ncr->command[1] & 0x1f) | (ncr->msglun << 5); - } + if (ncr->command_pos == cmd_len[(ncr->command[0] >> 5) & 7]) { + if (ncr->is_msgout) { + ncr->is_msgout = 0; + // ncr->command[1] = (ncr->command[1] & 0x1f) | (ncr->msglun << 5); + } - /*Reset data position to default*/ - ncr->data_pos = 0; + /*Reset data position to default*/ + ncr->data_pos = 0; - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); - dev->buffer_length = -1; - 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->buffer_length, dev->phase); + ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); + dev->buffer_length = -1; + 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->buffer_length, dev->phase); - ncr_dev->period = 1.0; - ncr->wait_data = 4; - ncr->data_wait = 0; + ncr_dev->period = 1.0; + ncr->wait_data = 4; + ncr->data_wait = 0; - if (dev->status == SCSI_STATUS_OK) { - /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ - if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { - p = scsi_device_get_callback(dev); - if (p <= 0.0) { - ncr_dev->period = 0.2; - } else { - ncr_dev->period = p / ((double) dev->buffer_length); - } - ncr->data_wait |= 2; - ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i\n", ncr->target_id, ncr->command[0], p, ncr_dev->period, dev->buffer_length); - } - } - ncr->new_phase = dev->phase; - } - } - break; - case STATE_DATAIN: - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - if (ncr->data_pos >= dev->buffer_length) { - ncr->cur_bus &= ~BUS_REQ; - scsi_device_command_phase1(dev); - ncr->new_phase = SCSI_PHASE_STATUS; - ncr->wait_data = 4; - ncr->wait_complete = 8; - } else { - ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++]; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; - if (ncr->data_wait & 2) - ncr->data_wait &= ~2; - if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ - ncr->data_wait |= 1; - ncr_log("DMA mode idle in\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } else - ncr->clear_req = 3; - ncr->cur_bus &= ~BUS_REQ; - ncr->new_phase = SCSI_PHASE_DATA_IN; - } - } - break; - case STATE_DATAOUT: - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus); + if (dev->status == SCSI_STATUS_OK) { + /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ + if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { + p = scsi_device_get_callback(dev); + if (p <= 0.0) { + ncr_dev->period = 0.2; + } else { + ncr_dev->period = p / ((double) dev->buffer_length); + } + ncr->data_wait |= 2; + ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i\n", ncr->target_id, ncr->command[0], p, ncr_dev->period, dev->buffer_length); + } + } + ncr->new_phase = dev->phase; + } + } + break; + case STATE_DATAIN: + dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { + if (ncr->data_pos >= dev->buffer_length) { + ncr->cur_bus &= ~BUS_REQ; + scsi_device_command_phase1(dev); + ncr->new_phase = SCSI_PHASE_STATUS; + ncr->wait_data = 4; + ncr->wait_complete = 8; + } else { + ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++]; + ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; + if (ncr->data_wait & 2) + ncr->data_wait &= ~2; + if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ + ncr->data_wait |= 1; + ncr_log("DMA mode idle in\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period); + } else + ncr->clear_req = 3; + ncr->cur_bus &= ~BUS_REQ; + ncr->new_phase = SCSI_PHASE_DATA_IN; + } + } + break; + case STATE_DATAOUT: + dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { + dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus); - if (ncr->data_pos >= dev->buffer_length) { - ncr->cur_bus &= ~BUS_REQ; - scsi_device_command_phase1(dev); - ncr->new_phase = SCSI_PHASE_STATUS; - ncr->wait_data = 4; - ncr->wait_complete = 8; - } else { - /*More data is to be transferred, place a request*/ - if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ - ncr->data_wait |= 1; - ncr_log("DMA mode idle out\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } else { - ncr->clear_req = 3; - } - ncr->cur_bus &= ~BUS_REQ; - ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); - } - } - break; - case STATE_STATUS: - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - /*All transfers done, wait until next transfer*/ - scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], SCSI_LUN_USE_CDB); - ncr->cur_bus &= ~BUS_REQ; - ncr->new_phase = SCSI_PHASE_MESSAGE_IN; - ncr->wait_data = 4; - ncr->wait_complete = 8; - } - break; - case STATE_MESSAGEIN: - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - ncr->cur_bus &= ~BUS_REQ; - ncr->new_phase = BUS_IDLE; - ncr->wait_data = 4; - } - break; - case STATE_MESSAGEOUT: - ncr_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - ncr->msgout[ncr->msgout_pos++] = BUS_GETDATA(bus); - msglen = getmsglen(ncr->msgout, ncr->msgout_pos); - if (ncr->msgout_pos >= msglen) { - if ((ncr->msgout[0] & (0x80 | 0x20)) == 0x80) - ncr->msglun = ncr->msgout[0] & 7; - ncr->cur_bus &= ~BUS_REQ; - ncr->state = STATE_MESSAGE_ID; - } - } - break; - case STATE_MESSAGE_ID: - if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], ncr->msglun); - ncr->state = STATE_COMMAND; - ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); - ncr->command_pos = 0; - SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); - } - break; + if (ncr->data_pos >= dev->buffer_length) { + ncr->cur_bus &= ~BUS_REQ; + scsi_device_command_phase1(dev); + ncr->new_phase = SCSI_PHASE_STATUS; + ncr->wait_data = 4; + ncr->wait_complete = 8; + } else { + /*More data is to be transferred, place a request*/ + if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ + ncr->data_wait |= 1; + ncr_log("DMA mode idle out\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period); + } else { + ncr->clear_req = 3; + } + ncr->cur_bus &= ~BUS_REQ; + ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); + } + } + break; + case STATE_STATUS: + if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { + /*All transfers done, wait until next transfer*/ + scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], SCSI_LUN_USE_CDB); + ncr->cur_bus &= ~BUS_REQ; + ncr->new_phase = SCSI_PHASE_MESSAGE_IN; + ncr->wait_data = 4; + ncr->wait_complete = 8; + } + break; + case STATE_MESSAGEIN: + if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { + ncr->cur_bus &= ~BUS_REQ; + ncr->new_phase = BUS_IDLE; + ncr->wait_data = 4; + } + break; + case STATE_MESSAGEOUT: + ncr_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); + if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { + ncr->msgout[ncr->msgout_pos++] = BUS_GETDATA(bus); + msglen = getmsglen(ncr->msgout, ncr->msgout_pos); + if (ncr->msgout_pos >= msglen) { + if ((ncr->msgout[0] & (0x80 | 0x20)) == 0x80) + ncr->msglun = ncr->msgout[0] & 7; + ncr->cur_bus &= ~BUS_REQ; + ncr->state = STATE_MESSAGE_ID; + } + } + break; + case STATE_MESSAGE_ID: + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { + ncr_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], ncr->msglun); + ncr->state = STATE_COMMAND; + ncr->cur_bus = BUS_BSY | BUS_REQ; + ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); + ncr->command_pos = 0; + SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); + } + break; } ncr->bus_in = bus; } - static void ncr_write(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 = &scsi_devices[ncr_dev->bus][ncr->target_id]; - int bus_host = 0; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + int bus_host = 0; - ncr_log("NCR5380 write(%04x,%02x)\n",port & 7,val); + ncr_log("NCR5380 write(%04x,%02x)\n", port & 7, val); switch (port & 7) { - case 0: /* Output data register */ - ncr_log("Write: Output data register, val = %02x\n", val); - ncr->output_data = val; - break; + case 0: /* Output data register */ + ncr_log("Write: Output data register, val = %02x\n", val); + ncr->output_data = val; + break; - case 1: /* Initiator Command Register */ - ncr_log("Write: Initiator command register\n"); - if ((val & 0x80) && !(ncr->icr & 0x80)) { - ncr_log("Resetting the 5380\n"); - ncr_reset(ncr_dev, &ncr_dev->ncr); - } - ncr->icr = val; - break; + case 1: /* Initiator Command Register */ + ncr_log("Write: Initiator command register\n"); + if ((val & 0x80) && !(ncr->icr & 0x80)) { + ncr_log("Resetting the 5380\n"); + ncr_reset(ncr_dev, &ncr_dev->ncr); + } + ncr->icr = val; + break; - case 2: /* Mode register */ - ncr_log("Write: Mode register, val=%02x\n", val & MODE_DMA); - if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) { - ncr->icr &= ~ICR_ARB_LOST; - ncr->icr |= ICR_ARB_IN_PROGRESS; - } + case 2: /* Mode register */ + ncr_log("Write: Mode register, val=%02x\n", val & MODE_DMA); + if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) { + ncr->icr &= ~ICR_ARB_LOST; + ncr->icr |= ICR_ARB_IN_PROGRESS; + } - ncr->mode = val; + ncr->mode = val; - if (ncr_dev->type == 3) { - /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->t128.block_loaded && (ncr->mode & MODE_DMA)) { - ncr_log("Continuing DMA mode\n"); - ncr_timer_on(ncr_dev, ncr, 0); - } + if (ncr_dev->type == 3) { + /*Don't stop the timer until it finishes the transfer*/ + if (ncr_dev->t128.block_loaded && (ncr->mode & MODE_DMA)) { + ncr_log("Continuing DMA mode\n"); + ncr_timer_on(ncr_dev, ncr, 0); + } - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr_dev->t128.block_loaded && !(ncr->mode & MODE_DMA)) { - ncr_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - } else { - /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { - ncr_log("Continuing DMA mode\n"); - ncr_timer_on(ncr_dev, ncr, 0); - } + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ + if (!ncr_dev->t128.block_loaded && !(ncr->mode & MODE_DMA)) { + ncr_log("No DMA mode\n"); + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } + } else { + /*Don't stop the timer until it finishes the transfer*/ + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + ncr_log("Continuing DMA mode\n"); + ncr_timer_on(ncr_dev, ncr, 0); + } - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { - ncr_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - } - break; + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ + if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { + ncr_log("No DMA mode\n"); + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } + } + break; - case 3: /* Target Command Register */ - ncr_log("Write: Target Command register\n"); - ncr->tcr = val; - break; + case 3: /* Target Command Register */ + ncr_log("Write: Target Command register\n"); + ncr->tcr = val; + break; - case 4: /* Select Enable Register */ - ncr_log("Write: Select Enable register\n"); - break; + case 4: /* Select Enable Register */ + ncr_log("Write: Select Enable register\n"); + break; - case 5: /* start DMA Send */ - ncr_log("Write: start DMA send register\n"); - /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ - ncr->dma_mode = DMA_SEND; - if (ncr_dev->type == 3) { - if (dev->buffer_length > 0) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); + case 5: /* start DMA Send */ + ncr_log("Write: start DMA send register\n"); + /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ + ncr->dma_mode = DMA_SEND; + if (ncr_dev->type == 3) { + if (dev->buffer_length > 0) { + memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_log("DMA send timer start, enabled? = %i\n", timer_is_enabled(&ncr_dev->timer)); - ncr_dev->t128.block_count = dev->buffer_length >> 9; - ncr_dev->t128.block_loaded = 1; + ncr_log("DMA send timer start, enabled? = %i\n", timer_is_enabled(&ncr_dev->timer)); + ncr_dev->t128.block_count = dev->buffer_length >> 9; + ncr_dev->t128.block_loaded = 1; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status |= 0x04; - } - } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status |= 0x04; + } + } else { + if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA send timer on\n"); - ncr_timer_on(ncr_dev, ncr, 0); - } - } - break; + ncr_log("DMA send timer on\n"); + ncr_timer_on(ncr_dev, ncr, 0); + } + } + break; - case 7: /* start DMA Initiator Receive */ - ncr_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); - /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ - ncr->dma_mode = DMA_INITIATOR_RECEIVE; - if (ncr_dev->type == 3) { - ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", timer_is_enabled(&ncr_dev->timer), ncr->command[0], dev->buffer_length); - if (dev->buffer_length > 0) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); + case 7: /* start DMA Initiator Receive */ + ncr_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); + /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ + ncr->dma_mode = DMA_INITIATOR_RECEIVE; + if (ncr_dev->type == 3) { + ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", timer_is_enabled(&ncr_dev->timer), ncr->command[0], dev->buffer_length); + if (dev->buffer_length > 0) { + memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_dev->t128.block_count = dev->buffer_length >> 9; + ncr_dev->t128.block_count = dev->buffer_length >> 9; - if (dev->buffer_length < 512) - ncr_dev->t128.block_count = 1; + if (dev->buffer_length < 512) + ncr_dev->t128.block_count = 1; - ncr_dev->t128.block_loaded = 1; + ncr_dev->t128.block_loaded = 1; - ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); - ncr_dev->t128.status |= 0x04; - timer_on_auto(&ncr_dev->timer, 0.02); - } - } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); + ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); + ncr_dev->t128.status |= 0x04; + timer_on_auto(&ncr_dev->timer, 0.02); + } + } else { + if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA receive timer start\n"); - ncr_timer_on(ncr_dev, ncr, 0); - } - } - break; + ncr_log("DMA receive timer start\n"); + ncr_timer_on(ncr_dev, ncr, 0); + } + } + break; - default: - ncr_log("NCR5380: bad write %04x %02x\n", port, val); - break; + default: + ncr_log("NCR5380: bad write %04x %02x\n", port, val); + break; } if (ncr->dma_mode == DMA_IDLE || ncr_dev->type == 0 || ncr_dev->type >= 3) { - bus_host = get_bus_host(ncr); - ncr_bus_update(priv, bus_host); + bus_host = get_bus_host(ncr); + ncr_bus_update(priv, bus_host); } } - static uint8_t ncr_read(uint16_t port, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - uint8_t ret = 0xff; - int bus, bus_state; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + uint8_t ret = 0xff; + int bus, bus_state; switch (port & 7) { - case 0: /* Current SCSI data */ - ncr_log("Read: Current SCSI data register\n"); - if (ncr->icr & ICR_DBP) { - /*Return the data from the output register if on data bus phase from ICR*/ - ncr_log("Data Bus Phase, ret = %02x\n", ncr->output_data); - ret = ncr->output_data; - } else { - /*Return the data from the SCSI bus*/ - ncr_bus_read(ncr_dev); - ncr_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); - ret = BUS_GETDATA(ncr->cur_bus); - } - break; + case 0: /* Current SCSI data */ + ncr_log("Read: Current SCSI data register\n"); + if (ncr->icr & ICR_DBP) { + /*Return the data from the output register if on data bus phase from ICR*/ + ncr_log("Data Bus Phase, ret = %02x\n", ncr->output_data); + ret = ncr->output_data; + } else { + /*Return the data from the SCSI bus*/ + ncr_bus_read(ncr_dev); + ncr_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); + ret = BUS_GETDATA(ncr->cur_bus); + } + break; - case 1: /* Initiator Command Register */ - ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); - ret = ncr->icr; - break; + case 1: /* Initiator Command Register */ + ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); + ret = ncr->icr; + break; - case 2: /* Mode register */ - if (((ncr->mode & 0x30) == 0x30) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) - ncr->mode = 0; - if (((ncr->mode & 0x20) == 0x20) && (ncr_dev->type == 0)) - ncr->mode = 0; + case 2: /* Mode register */ + if (((ncr->mode & 0x30) == 0x30) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) + ncr->mode = 0; + if (((ncr->mode & 0x20) == 0x20) && (ncr_dev->type == 0)) + ncr->mode = 0; - ncr_log("Read: Mode register\n"); - ret = ncr->mode; - break; + ncr_log("Read: Mode register\n"); + ret = ncr->mode; + break; - case 3: /* Target Command Register */ - ncr_log("Read: Target Command register, NCR target stat=%02x\n", ncr->tcr); - ret = ncr->tcr; - break; + case 3: /* Target Command Register */ + ncr_log("Read: Target Command register, NCR target stat=%02x\n", ncr->tcr); + ret = ncr->tcr; + break; - case 4: /* Current SCSI Bus status */ - ncr_log("Read: SCSI bus status register\n"); - ret = 0; - ncr_bus_read(ncr_dev); - ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); - ret |= (ncr->cur_bus & 0xff); - if ((ncr->icr & ICR_SEL) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) - ret |= 0x02; - if ((ncr->icr & ICR_BSY) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) - ret |= 0x40; - break; + case 4: /* Current SCSI Bus status */ + ncr_log("Read: SCSI bus status register\n"); + ret = 0; + ncr_bus_read(ncr_dev); + ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); + ret |= (ncr->cur_bus & 0xff); + if ((ncr->icr & ICR_SEL) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) + ret |= 0x02; + if ((ncr->icr & ICR_BSY) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) + ret |= 0x40; + break; - case 5: /* Bus and Status register */ - ncr_log("Read: Bus and Status register\n"); - ret = 0; + case 5: /* Bus and Status register */ + ncr_log("Read: Bus and Status register\n"); + ret = 0; - bus = get_bus_host(ncr); - ncr_log("Get host from Interrupt\n"); + bus = get_bus_host(ncr); + ncr_log("Get host from Interrupt\n"); - /*Check if the phase in process matches with TCR's*/ - if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { - ncr_log("Phase match\n"); - ret |= STATUS_PHASE_MATCH; - } + /*Check if the phase in process matches with TCR's*/ + if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { + ncr_log("Phase match\n"); + ret |= STATUS_PHASE_MATCH; + } - ncr_bus_read(ncr_dev); - bus = ncr->cur_bus; + ncr_bus_read(ncr_dev); + bus = ncr->cur_bus; - if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))) - ret |= STATUS_ACK; - if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))) - ret |= 0x02; + if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))) + ret |= STATUS_ACK; + if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))) + ret |= 0x02; - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { - ncr_log("Entering DMA mode\n"); - ret |= STATUS_DRQ; + if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { + ncr_log("Entering DMA mode\n"); + ret |= STATUS_DRQ; - bus_state = 0; + bus_state = 0; - if (bus & BUS_IO) - bus_state |= TCR_IO; - if (bus & BUS_CD) - bus_state |= TCR_CD; - if (bus & BUS_MSG) - bus_state |= TCR_MSG; - if ((ncr->tcr & 7) != bus_state) { - ncr_irq(ncr_dev, ncr, 1); - ncr_log("IRQ issued\n"); - } - } - if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr_log("Busy error\n"); - ret |= STATUS_BUSY_ERROR; - } - ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); - break; + if (bus & BUS_IO) + bus_state |= TCR_IO; + if (bus & BUS_CD) + bus_state |= TCR_CD; + if (bus & BUS_MSG) + bus_state |= TCR_MSG; + if ((ncr->tcr & 7) != bus_state) { + ncr_irq(ncr_dev, ncr, 1); + ncr_log("IRQ issued\n"); + } + } + if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + ncr_log("Busy error\n"); + ret |= STATUS_BUSY_ERROR; + } + ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); + break; - case 6: - ret = ncr->tx_data; - break; + case 6: + ret = ncr->tx_data; + break; - case 7: /* reset Parity/Interrupt */ - ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20); - ncr_irq(ncr_dev, ncr, 0); - ncr_log("Reset Interrupt\n"); - break; + case 7: /* reset Parity/Interrupt */ + ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20); + ncr_irq(ncr_dev, ncr, 0); + ncr_log("Reset Interrupt\n"); + break; - default: - ncr_log("NCR5380: bad read %04x\n", port); - break; + default: + ncr_log("NCR5380: bad read %04x\n", port); + break; } ncr_log("NCR5380 read(%04x)=%02x\n", port & 7, ret); - return(ret); + return (ret); } - /* Memory-mapped I/O READ handler. */ static uint8_t memio_read(uint32_t addr, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + uint8_t ret = 0xff; addr &= 0x3fff; if (addr < 0x2000) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; + ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; else if (addr < 0x3800) - ret = 0xff; + ret = 0xff; else if (addr >= 0x3a00) - ret = ncr_dev->ext_ram[addr - 0x3a00]; - else switch (addr & 0x3f80) { - case 0x3800: + ret = ncr_dev->ext_ram[addr - 0x3a00]; + else + switch (addr & 0x3f80) { + case 0x3800: #if ENABLE_NCR5380_LOG - ncr_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr_dev->int_ram[addr & 0x3f]); + ncr_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr_dev->int_ram[addr & 0x3f]); #endif - ret = ncr_dev->int_ram[addr & 0x3f]; - break; + ret = ncr_dev->int_ram[addr & 0x3f]; + break; - case 0x3880: + case 0x3880: #if ENABLE_NCR5380_LOG - ncr_log("Read 53c80 %04x\n", addr); + ncr_log("Read 53c80 %04x\n", addr); #endif - ret = ncr_read(addr, ncr_dev); - break; + ret = ncr_read(addr, ncr_dev); + break; - case 0x3900: - if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ret = 0xff; - } else { - ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; + case 0x3900: + if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { + ret = 0xff; + } else { + ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; - if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr_log("Transfer busy read, status = %02x\n", ncr_dev->status_ctrl); - } - } - break; + if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { + ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr_log("Transfer busy read, status = %02x\n", ncr_dev->status_ctrl); + } + } + break; - case 0x3980: - switch (addr) { - case 0x3980: /* status */ - ret = ncr_dev->status_ctrl; - ncr_log("NCR status ctrl read=%02x\n", ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY); - if (!ncr_dev->ncr_busy) - ret |= STATUS_53C80_ACCESSIBLE; - break; + case 0x3980: + switch (addr) { + case 0x3980: /* status */ + ret = ncr_dev->status_ctrl; + ncr_log("NCR status ctrl read=%02x\n", ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY); + if (!ncr_dev->ncr_busy) + ret |= STATUS_53C80_ACCESSIBLE; + break; - case 0x3981: /* block counter register*/ - ret = ncr_dev->block_count; - break; + case 0x3981: /* block counter register*/ + ret = ncr_dev->block_count; + break; - case 0x3982: /* switch register read */ - ret = 0xff; - break; + case 0x3982: /* switch register read */ + ret = 0xff; + break; - case 0x3983: - ret = 0xff; - break; - } - break; - } + case 0x3983: + ret = 0xff; + break; + } + break; + } #if ENABLE_NCR5380_LOG if (addr >= 0x3880) - ncr_log("memio_read(%08x)=%02x\n", addr, ret); + ncr_log("memio_read(%08x)=%02x\n", addr, ret); #endif - return(ret); + return (ret); } - /* Memory-mapped I/O WRITE handler. */ static void memio_write(uint32_t addr, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; addr &= 0x3fff; if (addr >= 0x3a00) - ncr_dev->ext_ram[addr - 0x3a00] = val; - else switch (addr & 0x3f80) { - case 0x3800: - ncr_dev->int_ram[addr & 0x3f] = val; - break; + ncr_dev->ext_ram[addr - 0x3a00] = val; + else + switch (addr & 0x3f80) { + case 0x3800: + ncr_dev->int_ram[addr & 0x3f] = val; + break; - case 0x3880: - ncr_write(addr, val, ncr_dev); - break; + case 0x3880: + ncr_write(addr, val, ncr_dev); + break; - case 0x3900: - if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR) && ncr_dev->buffer_host_pos < MIN(128, dev->buffer_length)) { - ncr_dev->buffer[ncr_dev->buffer_host_pos++] = val; + case 0x3900: + if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR) && ncr_dev->buffer_host_pos < MIN(128, dev->buffer_length)) { + ncr_dev->buffer[ncr_dev->buffer_host_pos++] = val; - ncr_log("Write host pos = %i, val = %02x\n", ncr_dev->buffer_host_pos, val); + ncr_log("Write host pos = %i, val = %02x\n", ncr_dev->buffer_host_pos, val); - if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 1; - } - } - break; + if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { + ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr_dev->ncr_busy = 1; + } + } + break; - case 0x3980: - switch (addr) { - case 0x3980: /* Control */ - if ((val & CTRL_DATA_DIR) && !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - } - else if (!(val & CTRL_DATA_DIR) && (ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - ncr_dev->status_ctrl = (ncr_dev->status_ctrl & 0x87) | (val & 0x78); - break; + case 0x3980: + switch (addr) { + case 0x3980: /* Control */ + if ((val & CTRL_DATA_DIR) && !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { + ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); + ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else if (!(val & CTRL_DATA_DIR) && (ncr_dev->status_ctrl & CTRL_DATA_DIR)) { + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + ncr_dev->status_ctrl = (ncr_dev->status_ctrl & 0x87) | (val & 0x78); + break; - case 0x3981: /* block counter register */ - ncr_log("Write block counter register: val=%d, dma mode = %i, period = %lf\n", val, ncr->dma_mode, ncr_dev->period); - ncr_dev->block_count = val; - ncr_dev->block_count_loaded = 1; + case 0x3981: /* block counter register */ + ncr_log("Write block counter register: val=%d, dma mode = %i, period = %lf\n", val, ncr->dma_mode, ncr_dev->period); + ncr_dev->block_count = val; + ncr_dev->block_count_loaded = 1; - if (ncr->mode & MODE_DMA) - ncr_timer_on(ncr_dev, ncr, 0); + if (ncr->mode & MODE_DMA) + ncr_timer_on(ncr_dev, ncr, 0); - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { - ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - break; - } - break; - } + if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { + ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); + ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else { + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + break; + } + break; + } } - /* Memory-mapped I/O READ handler for the Trantor T130B. */ static uint8_t t130b_read(uint32_t addr, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - uint8_t ret = 0xff; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + uint8_t ret = 0xff; addr &= 0x3fff; if (addr < 0x1800) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; + ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; else if (addr >= 0x1800 && addr < 0x1880) - ret = ncr_dev->ext_ram[addr & 0x7f]; + ret = ncr_dev->ext_ram[addr & 0x7f]; ncr_log("MEM: Reading %02X from %08X\n", ret, addr); - return(ret); + return (ret); } - /* Memory-mapped I/O WRITE handler for the Trantor T130B. */ static void t130b_write(uint32_t addr, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; addr &= 0x3fff; ncr_log("MEM: Writing %02X to %08X\n", val, addr); if (addr >= 0x1800 && addr < 0x1880) - ncr_dev->ext_ram[addr & 0x7f] = val; + ncr_dev->ext_ram[addr & 0x7f] = val; } - static uint8_t t130b_in(uint16_t port, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - uint8_t ret = 0xff; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + uint8_t ret = 0xff; switch (port & 0x0f) { - case 0x00: case 0x01: case 0x02: case 0x03: - ret = memio_read((port & 7) | 0x3980, ncr_dev); - break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + ret = memio_read((port & 7) | 0x3980, ncr_dev); + break; - case 0x04: case 0x05: - ret = memio_read(0x3900, ncr_dev); - break; + case 0x04: + case 0x05: + ret = memio_read(0x3900, ncr_dev); + break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - ret = ncr_read(port, ncr_dev); - break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = ncr_read(port, ncr_dev); + break; } ncr_log("I/O: Reading %02X from %04X\n", ret, port); - return(ret); + return (ret); } - static void t130b_out(uint16_t port, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_log("I/O: Writing %02X to %04X\n", val, port); switch (port & 0x0f) { - case 0x00: case 0x01: case 0x02: case 0x03: - memio_write((port & 7) | 0x3980, val, ncr_dev); - break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + memio_write((port & 7) | 0x3980, val, ncr_dev); + break; - case 0x04: case 0x05: - memio_write(0x3900, val, ncr_dev); - break; + case 0x04: + case 0x05: + memio_write(0x3900, val, ncr_dev); + break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - ncr_write(port, val, ncr_dev); - break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ncr_write(port, val, ncr_dev); + break; } } static void ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) { - int bus, c = 0; + int bus, c = 0; uint8_t data; if (scsi_device_get_callback(dev) > 0.0) - ncr_timer_on(ncr_dev, ncr, 1); + ncr_timer_on(ncr_dev, ncr, 1); else - ncr_timer_on(ncr_dev, ncr, 0); + ncr_timer_on(ncr_dev, ncr, 0); for (c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; } /* Data ready. */ if (ncr_dev->type == 3) - data = ncr_dev->t128.buffer[ncr_dev->t128.pos]; - else - data = ncr_dev->buffer[ncr_dev->buffer_pos]; + data = ncr_dev->t128.buffer[ncr_dev->t128.pos]; + else + data = ncr_dev->buffer[ncr_dev->buffer_pos]; bus = get_bus_host(ncr) & ~BUS_DATAMASK; bus |= BUS_SETDATA(data); ncr_bus_update(ncr_dev, bus | BUS_ACK); ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - if (ncr_dev->type == 3) { - ncr_dev->t128.pos++; - ncr_log("Buffer pos for writing = %d, data = %02x\n", ncr_dev->t128.pos, data); + if (ncr_dev->type == 3) { + ncr_dev->t128.pos++; + ncr_log("Buffer pos for writing = %d, data = %02x\n", ncr_dev->t128.pos, data); - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } else { - ncr_dev->buffer_pos++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); + if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.pos = 0; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status &= ~0x02; + ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); + if (!ncr_dev->t128.block_count) { + ncr_dev->t128.block_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + return; + } + } else { + ncr_dev->buffer_pos++; + ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } + if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->ncr_busy = 0; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + return; + } + } ncr_dma_send(ncr_dev, ncr, dev); } static void ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) { - int bus, c = 0; + int bus, c = 0; uint8_t temp; - if (scsi_device_get_callback(dev) > 0.0) { - ncr_timer_on(ncr_dev, ncr, 1); - } else { - ncr_timer_on(ncr_dev, ncr, 0); - } + if (scsi_device_get_callback(dev) > 0.0) { + ncr_timer_on(ncr_dev, ncr, 1); + } else { + ncr_timer_on(ncr_dev, ncr, 0); + } for (c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; } /* Data ready. */ @@ -1176,282 +1182,282 @@ ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) ncr_bus_update(ncr_dev, bus | BUS_ACK); ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - if (ncr_dev->type == 3) { - ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; - ncr_log("Buffer pos for reading = %d, temp = %02x\n", ncr_dev->t128.pos, temp); + if (ncr_dev->type == 3) { + ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; + ncr_log("Buffer pos for reading = %d, temp = %02x\n", ncr_dev->t128.pos, temp); - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } else { - ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; - ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); + if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.pos = 0; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status &= ~0x02; + ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); + if (!ncr_dev->t128.block_count) { + ncr_dev->t128.block_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + return; + } + } else { + ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; + ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } + if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + return; + } + } ncr_dma_initiator_receive(ncr_dev, ncr, dev); } static void ncr_callback(void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - if (ncr_dev->type == 3) { - ncr_log("DMA Callback, load = %i\n", ncr_dev->t128.block_loaded); - if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { - ncr_log("Timer on! Host POS = %i, status = %02x, DMA mode = %i, Period = %lf\n", ncr_dev->t128.host_pos, ncr_dev->t128.status, ncr->dma_mode, scsi_device_get_callback(dev)); - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length) && ncr_dev->t128.block_count) { - ncr_dev->t128.status |= 0x04; - } - ncr_timer_on(ncr_dev, ncr, 0); - } - } else { - ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl); - if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded) { - ncr_timer_on(ncr_dev, ncr, 0); - } - } - - if (ncr->data_wait & 1) { - ncr->clear_req = 3; - ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) { - return; - } + if (ncr_dev->type == 3) { + ncr_log("DMA Callback, load = %i\n", ncr_dev->t128.block_loaded); + if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { + ncr_log("Timer on! Host POS = %i, status = %02x, DMA mode = %i, Period = %lf\n", ncr_dev->t128.host_pos, ncr_dev->t128.status, ncr->dma_mode, scsi_device_get_callback(dev)); + if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length) && ncr_dev->t128.block_count) { + ncr_dev->t128.status |= 0x04; + } + ncr_timer_on(ncr_dev, ncr, 0); + } + } else { + ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl); + if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded) { + ncr_timer_on(ncr_dev, ncr, 0); + } } - switch(ncr->dma_mode) { - case DMA_SEND: - if (ncr_dev->type != 3) { - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { - ncr_log("DMA_SEND with DMA direction set wrong\n"); - break; - } + if (ncr->data_wait & 1) { + ncr->clear_req = 3; + ncr->data_wait &= ~1; + if (ncr->dma_mode == DMA_IDLE) { + return; + } + } - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Write buffer status ready\n"); - break; - } + switch (ncr->dma_mode) { + case DMA_SEND: + if (ncr_dev->type != 3) { + if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { + ncr_log("DMA_SEND with DMA direction set wrong\n"); + break; + } - if (!ncr_dev->block_count_loaded) - break; - } else { - if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Write status busy\n"); - break; - } + if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr_log("Write buffer status ready\n"); + break; + } - if (!ncr_dev->t128.block_loaded) { - ncr_log("Write block not loaded\n"); - break; - } + if (!ncr_dev->block_count_loaded) + break; + } else { + if (!(ncr_dev->t128.status & 0x04)) { + ncr_log("Write status busy\n"); + break; + } - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) - break; - } - ncr_dma_send(ncr_dev, ncr, dev); - break; + if (!ncr_dev->t128.block_loaded) { + ncr_log("Write block not loaded\n"); + break; + } - case DMA_INITIATOR_RECEIVE: - if (ncr_dev->type != 3) { - if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); - break; - } + if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) + break; + } + ncr_dma_send(ncr_dev, ncr, dev); + break; - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Read buffer status ready\n"); - break; - } + case DMA_INITIATOR_RECEIVE: + if (ncr_dev->type != 3) { + if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { + ncr_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); + break; + } - if (!ncr_dev->block_count_loaded) - break; - } else { - if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Read status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); - break; - } + if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr_log("Read buffer status ready\n"); + break; + } - if (!ncr_dev->t128.block_loaded) { - ncr_log("Read block not loaded\n"); - break; - } + if (!ncr_dev->block_count_loaded) + break; + } else { + if (!(ncr_dev->t128.status & 0x04)) { + ncr_log("Read status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); + break; + } - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) - break; - } - ncr_dma_initiator_receive(ncr_dev, ncr, dev); - break; + if (!ncr_dev->t128.block_loaded) { + ncr_log("Read block not loaded\n"); + break; + } + + if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) + break; + } + ncr_dma_initiator_receive(ncr_dev, ncr, dev); + break; } ncr_bus_read(ncr_dev); if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr_log("Updating DMA\n"); - ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; - timer_on_auto(&ncr_dev->timer, 10.0); + ncr_log("Updating DMA\n"); + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + timer_on_auto(&ncr_dev->timer, 10.0); } } static uint8_t t128_read(uint32_t addr, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + uint8_t ret = 0xff; addr &= 0x3fff; if (addr >= 0 && addr < 0x1800) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; + ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; else if (addr >= 0x1800 && addr < 0x1880) - ret = ncr_dev->t128.ext_ram[addr & 0x7f]; - else if (addr >= 0x1c00 && addr < 0x1c20) { - ret = ncr_dev->t128.ctrl; - } else if (addr >= 0x1c20 && addr < 0x1c40) { - ret = ncr_dev->t128.status; - ncr_log("T128 status read = %02x, cur bus = %02x, req = %02x, dma = %02x\n", ret, ncr->cur_bus, ncr->cur_bus & BUS_REQ, ncr->mode & MODE_DMA); - } else if (addr >= 0x1d00 && addr < 0x1e00) { - if (addr >= 0x1d00 && addr < 0x1d20) - ret = ncr_read(0, ncr_dev); - else if (addr >= 0x1d20 && addr < 0x1d40) - ret = ncr_read(1, ncr_dev); - else if (addr >= 0x1d40 && addr < 0x1d60) - ret = ncr_read(2, ncr_dev); - else if (addr >= 0x1d60 && addr < 0x1d80) - ret = ncr_read(3, ncr_dev); - else if (addr >= 0x1d80 && addr < 0x1da0) - ret = ncr_read(4, ncr_dev); - else if (addr >= 0x1da0 && addr < 0x1dc0) - ret = ncr_read(5, ncr_dev); - else if (addr >= 0x1dc0 && addr < 0x1de0) - ret = ncr_read(6, ncr_dev); - else if (addr >= 0x1de0 && addr < 0x1e00) - ret = ncr_read(7, ncr_dev); - } else if (addr >= 0x1e00 && addr < 0x2000) { - if (ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length) || ncr->dma_mode != DMA_INITIATOR_RECEIVE) { - ret = 0xff; - } else { - ret = ncr_dev->t128.buffer[ncr_dev->t128.host_pos++]; + ret = ncr_dev->t128.ext_ram[addr & 0x7f]; + else if (addr >= 0x1c00 && addr < 0x1c20) { + ret = ncr_dev->t128.ctrl; + } else if (addr >= 0x1c20 && addr < 0x1c40) { + ret = ncr_dev->t128.status; + ncr_log("T128 status read = %02x, cur bus = %02x, req = %02x, dma = %02x\n", ret, ncr->cur_bus, ncr->cur_bus & BUS_REQ, ncr->mode & MODE_DMA); + } else if (addr >= 0x1d00 && addr < 0x1e00) { + if (addr >= 0x1d00 && addr < 0x1d20) + ret = ncr_read(0, ncr_dev); + else if (addr >= 0x1d20 && addr < 0x1d40) + ret = ncr_read(1, ncr_dev); + else if (addr >= 0x1d40 && addr < 0x1d60) + ret = ncr_read(2, ncr_dev); + else if (addr >= 0x1d60 && addr < 0x1d80) + ret = ncr_read(3, ncr_dev); + else if (addr >= 0x1d80 && addr < 0x1da0) + ret = ncr_read(4, ncr_dev); + else if (addr >= 0x1da0 && addr < 0x1dc0) + ret = ncr_read(5, ncr_dev); + else if (addr >= 0x1dc0 && addr < 0x1de0) + ret = ncr_read(6, ncr_dev); + else if (addr >= 0x1de0 && addr < 0x1e00) + ret = ncr_read(7, ncr_dev); + } else if (addr >= 0x1e00 && addr < 0x2000) { + if (ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length) || ncr->dma_mode != DMA_INITIATOR_RECEIVE) { + ret = 0xff; + } else { + ret = ncr_dev->t128.buffer[ncr_dev->t128.host_pos++]; - ncr_log("Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, ncr_dev->t128.host_pos); + ncr_log("Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, ncr_dev->t128.host_pos); - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.status &= ~0x04; - ncr_log("Transfer busy read, status = %02x, period = %lf\n", ncr_dev->t128.status, ncr_dev->period); - if (ncr_dev->period == 0.2 || ncr_dev->period == 0.02) - timer_on_auto(&ncr_dev->timer, 40.2); - } else if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && scsi_device_get_callback(dev) > 100.0) - cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ - } - } + if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.status &= ~0x04; + ncr_log("Transfer busy read, status = %02x, period = %lf\n", ncr_dev->t128.status, ncr_dev->period); + if (ncr_dev->period == 0.2 || ncr_dev->period == 0.02) + timer_on_auto(&ncr_dev->timer, 40.2); + } else if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && scsi_device_get_callback(dev) > 100.0) + cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ + } + } - return(ret); + return (ret); } static void t128_write(uint32_t addr, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; addr &= 0x3fff; if (addr >= 0x1800 && addr < 0x1880) - ncr_dev->t128.ext_ram[addr & 0x7f] = val; - else if (addr >= 0x1c00 && addr < 0x1c20) { - if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) { - ncr_dev->t128.status |= 0x02; - ncr_log("Timer fired\n"); - } - ncr_dev->t128.ctrl = val; - ncr_log("T128 ctrl write = %02x\n", val); - } else if (addr >= 0x1d00 && addr < 0x1e00) { - if (addr >= 0x1d00 && addr < 0x1d20) - ncr_write(0, val, ncr_dev); - else if (addr >= 0x1d20 && addr < 0x1d40) - ncr_write(1, val, ncr_dev); - else if (addr >= 0x1d40 && addr < 0x1d60) - ncr_write(2, val, ncr_dev); - else if (addr >= 0x1d60 && addr < 0x1d80) - ncr_write(3, val, ncr_dev); - else if (addr >= 0x1d80 && addr < 0x1da0) - ncr_write(4, val, ncr_dev); - else if (addr >= 0x1da0 && addr < 0x1dc0) - ncr_write(5, val, ncr_dev); - else if (addr >= 0x1dc0 && addr < 0x1de0) - ncr_write(6, val, ncr_dev); - else if (addr >= 0x1de0 && addr < 0x1e00) - ncr_write(7, val, ncr_dev); - } else if (addr >= 0x1e00 && addr < 0x2000) { - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && ncr->dma_mode == DMA_SEND) { - ncr_dev->t128.buffer[ncr_dev->t128.host_pos] = val; - ncr_dev->t128.host_pos++; + ncr_dev->t128.ext_ram[addr & 0x7f] = val; + else if (addr >= 0x1c00 && addr < 0x1c20) { + if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) { + ncr_dev->t128.status |= 0x02; + ncr_log("Timer fired\n"); + } + ncr_dev->t128.ctrl = val; + ncr_log("T128 ctrl write = %02x\n", val); + } else if (addr >= 0x1d00 && addr < 0x1e00) { + if (addr >= 0x1d00 && addr < 0x1d20) + ncr_write(0, val, ncr_dev); + else if (addr >= 0x1d20 && addr < 0x1d40) + ncr_write(1, val, ncr_dev); + else if (addr >= 0x1d40 && addr < 0x1d60) + ncr_write(2, val, ncr_dev); + else if (addr >= 0x1d60 && addr < 0x1d80) + ncr_write(3, val, ncr_dev); + else if (addr >= 0x1d80 && addr < 0x1da0) + ncr_write(4, val, ncr_dev); + else if (addr >= 0x1da0 && addr < 0x1dc0) + ncr_write(5, val, ncr_dev); + else if (addr >= 0x1dc0 && addr < 0x1de0) + ncr_write(6, val, ncr_dev); + else if (addr >= 0x1de0 && addr < 0x1e00) + ncr_write(7, val, ncr_dev); + } else if (addr >= 0x1e00 && addr < 0x2000) { + if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && ncr->dma_mode == DMA_SEND) { + ncr_dev->t128.buffer[ncr_dev->t128.host_pos] = val; + ncr_dev->t128.host_pos++; - ncr_log("Write transfer, addr = %i, pos = %i, val = %02x\n", addr & 0x1ff, ncr_dev->t128.host_pos, val); + ncr_log("Write transfer, addr = %i, pos = %i, val = %02x\n", addr & 0x1ff, ncr_dev->t128.host_pos, val); - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.status &= ~0x04; - ncr_log("Transfer busy write, status = %02x\n", ncr_dev->t128.status); - timer_on_auto(&ncr_dev->timer, 0.02); - } - } else - ncr_log("Write PDMA addr = %i, val = %02x\n", addr & 0x1ff, val); - } + if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.status &= ~0x04; + ncr_log("Transfer busy write, status = %02x\n", ncr_dev->t128.status); + timer_on_auto(&ncr_dev->timer, 0.02); + } + } else + ncr_log("Write PDMA addr = %i, val = %02x\n", addr & 0x1ff, val); + } } static uint8_t rt1000b_mc_read(int port, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; - return(ncr_dev->pos_regs[port & 7]); + return (ncr_dev->pos_regs[port & 7]); } - static void rt1000b_mc_write(int port, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; mem_mapping_disable(&ncr_dev->bios_rom.mapping); mem_mapping_disable(&ncr_dev->mapping); @@ -1489,7 +1495,7 @@ rt1000b_mc_write(int port, uint8_t val, void *priv) static uint8_t rt1000b_mc_feedb(void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; return ncr_dev->pos_regs[2] & 1; } @@ -1497,8 +1503,8 @@ rt1000b_mc_feedb(void *priv) static void * ncr_init(const device_t *info) { - char *fn = NULL; - char temp[128]; + char *fn = NULL; + char temp[128]; ncr5380_t *ncr_dev; ncr_dev = malloc(sizeof(ncr5380_t)); @@ -1508,173 +1514,170 @@ ncr_init(const device_t *info) ncr_dev->bus = scsi_get_bus(); - switch(ncr_dev->type) { - case 0: /* Longshine LCS6821N */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - rom_init(&ncr_dev->bios_rom, LCS6821N_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + switch (ncr_dev->type) { + case 0: /* Longshine LCS6821N */ + ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); + ncr_dev->irq = device_get_config_int("irq"); + rom_init(&ncr_dev->bios_rom, LCS6821N_ROM, + ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - case 1: /* Rancho RT1000B/MC */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - ncr_dev->bios_ver = device_get_config_int("bios_ver"); - if (info->flags & DEVICE_MCA) { - ncr_dev->rom_addr = 0xd8000; - ncr_dev->bios_ver = 1; - } - - if (ncr_dev->bios_ver == 1) - fn = RT1000B_820R_ROM; - else - fn = RT1000B_810R_ROM; - - rom_init(&ncr_dev->bios_rom, fn, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - if (info->flags & DEVICE_MCA) { - mem_mapping_add(&ncr_dev->mapping, 0, 0, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - ncr_dev->pos_regs[0] = 0x8d; - ncr_dev->pos_regs[1] = 0x70; - mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev); - } else { mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - } - break; + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + break; - case 2: /* Trantor T130B */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->base = device_get_config_hex16("base"); - ncr_dev->irq = device_get_config_int("irq"); + case 1: /* Rancho RT1000B/MC */ + ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); + ncr_dev->irq = device_get_config_int("irq"); + ncr_dev->bios_ver = device_get_config_int("bios_ver"); + if (info->flags & DEVICE_MCA) { + ncr_dev->rom_addr = 0xd8000; + ncr_dev->bios_ver = 1; + } - if (ncr_dev->rom_addr > 0x00000) { - rom_init(&ncr_dev->bios_rom, T130B_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + if (ncr_dev->bios_ver == 1) + fn = RT1000B_820R_ROM; + else + fn = RT1000B_810R_ROM; - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - t130b_read, NULL, NULL, - t130b_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - } + rom_init(&ncr_dev->bios_rom, fn, + ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - io_sethandler(ncr_dev->base, 16, - t130b_in,NULL,NULL, t130b_out,NULL,NULL, ncr_dev); - break; + if (info->flags & DEVICE_MCA) { + mem_mapping_add(&ncr_dev->mapping, 0, 0, + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + ncr_dev->pos_regs[0] = 0x8d; + ncr_dev->pos_regs[1] = 0x70; + mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev); + } else { + mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + } + break; - case 3: /* Trantor T128 */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - ncr_dev->t128.bios_enabled = device_get_config_int("boot"); + case 2: /* Trantor T130B */ + ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); + ncr_dev->base = device_get_config_hex16("base"); + ncr_dev->irq = device_get_config_int("irq"); - if (ncr_dev->t128.bios_enabled) - rom_init(&ncr_dev->bios_rom, T128_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + if (ncr_dev->rom_addr > 0x00000) { + rom_init(&ncr_dev->bios_rom, T130B_ROM, + ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - t128_read, NULL, NULL, - t128_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; + mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, + t130b_read, NULL, NULL, + t130b_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + } - case 4: /* Corel LS2000 */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - rom_init(&ncr_dev->bios_rom, COREL_LS2000_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + io_sethandler(ncr_dev->base, 16, + t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr_dev); + break; - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; + case 3: /* Trantor T128 */ + ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); + ncr_dev->irq = device_get_config_int("irq"); + ncr_dev->t128.bios_enabled = device_get_config_int("boot"); + + if (ncr_dev->t128.bios_enabled) + rom_init(&ncr_dev->bios_rom, T128_ROM, + ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, + t128_read, NULL, NULL, + t128_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + break; + + case 4: /* Corel LS2000 */ + ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); + ncr_dev->irq = device_get_config_int("irq"); + rom_init(&ncr_dev->bios_rom, COREL_LS2000_ROM, + ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + break; } sprintf(temp, "%s: BIOS=%05X", ncr_dev->name, ncr_dev->rom_addr); if (ncr_dev->base != 0) - sprintf(&temp[strlen(temp)], " I/O=%04x", ncr_dev->base); + sprintf(&temp[strlen(temp)], " I/O=%04x", ncr_dev->base); if (ncr_dev->irq != 0) - sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); + sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); ncr_log("%s\n", temp); ncr_reset(ncr_dev, &ncr_dev->ncr); - if (ncr_dev->type < 3 || ncr_dev->type == 4) { - ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_host_pos = 128; - } else { - ncr_dev->t128.status = 0x04; - ncr_dev->t128.host_pos = 512; + if (ncr_dev->type < 3 || ncr_dev->type == 4) { + ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; + ncr_dev->buffer_host_pos = 128; + } else { + ncr_dev->t128.status = 0x04; + ncr_dev->t128.host_pos = 512; - if (!ncr_dev->t128.bios_enabled) - ncr_dev->t128.status |= 0x80; - } - timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0); + if (!ncr_dev->t128.bios_enabled) + ncr_dev->t128.status |= 0x80; + } + timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0); - return(ncr_dev); + return (ncr_dev); } - static void ncr_close(void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; if (ncr_dev) { - /* Tell the timer to terminate. */ - timer_stop(&ncr_dev->timer); + /* Tell the timer to terminate. */ + timer_stop(&ncr_dev->timer); - free(ncr_dev); - ncr_dev = NULL; + free(ncr_dev); + ncr_dev = NULL; } } - static int lcs6821n_available(void) { - return(rom_present(LCS6821N_ROM)); + return (rom_present(LCS6821N_ROM)); } - static int rt1000b_available(void) { - return(rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM)); + return (rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM)); } static int rt1000b_820_available(void) { - return(rom_present(RT1000B_820R_ROM)); + return (rom_present(RT1000B_820R_ROM)); } static int t130b_available(void) { - return(rom_present(T130B_ROM)); + return (rom_present(T130B_ROM)); } static int t128_available(void) { - return(rom_present(T128_ROM)); + return (rom_present(T128_ROM)); } static int corel_ls2000_available(void) { - return(rom_present(COREL_LS2000_ROM)); + return (rom_present(COREL_LS2000_ROM)); } // clang-format off @@ -1883,85 +1886,85 @@ static const device_config_t t128_config[] = { // clang-format on const device_t scsi_lcs6821n_device = { - .name = "Longshine LCS-6821N", + .name = "Longshine LCS-6821N", .internal_name = "lcs6821n", - .flags = DEVICE_ISA, - .local = 0, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, { .available = lcs6821n_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr5380_mmio_config + .force_redraw = NULL, + .config = ncr5380_mmio_config }; const device_t scsi_rt1000b_device = { - .name = "Rancho RT1000B", + .name = "Rancho RT1000B", .internal_name = "rt1000b", - .flags = DEVICE_ISA, - .local = 1, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 1, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, { .available = rt1000b_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = rancho_config + .force_redraw = NULL, + .config = rancho_config }; const device_t scsi_rt1000mc_device = { - .name = "Rancho RT1000B-MC", + .name = "Rancho RT1000B-MC", .internal_name = "rt1000mc", - .flags = DEVICE_MCA, - .local = 1, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 1, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, { .available = rt1000b_820_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = rancho_mc_config + .force_redraw = NULL, + .config = rancho_mc_config }; const device_t scsi_t130b_device = { - .name = "Trantor T130B", + .name = "Trantor T130B", .internal_name = "t130b", - .flags = DEVICE_ISA, - .local = 2, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 2, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, { .available = t130b_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = t130b_config + .force_redraw = NULL, + .config = t130b_config }; const device_t scsi_t128_device = { - .name = "Trantor T128", + .name = "Trantor T128", .internal_name = "t128", - .flags = DEVICE_ISA, - .local = 3, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 3, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, { .available = t128_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = t128_config + .force_redraw = NULL, + .config = t128_config }; const device_t scsi_ls2000_device = { - .name = "Corel LS2000", + .name = "Corel LS2000", .internal_name = "ls2000", - .flags = DEVICE_ISA, - .local = 4, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 4, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, { .available = corel_ls2000_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr5380_mmio_config + .force_redraw = NULL, + .config = ncr5380_mmio_config }; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 7a9344d62..ba5ccd002 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -45,190 +45,188 @@ #include <86box/scsi_device.h> #include <86box/scsi_ncr53c8xx.h> +#define NCR53C8XX_SDMS3_ROM "roms/scsi/ncr53c8xx/NCR307.BIN" +#define SYM53C8XX_SDMS4_ROM "roms/scsi/ncr53c8xx/8xx_64.rom" -#define NCR53C8XX_SDMS3_ROM "roms/scsi/ncr53c8xx/NCR307.BIN" -#define SYM53C8XX_SDMS4_ROM "roms/scsi/ncr53c8xx/8xx_64.rom" +#define HA_ID 7 -#define HA_ID 7 +#define CHIP_810 0x01 +#define CHIP_820 0x02 +#define CHIP_825 0x03 +#define CHIP_815 0x04 +#define CHIP_810AP 0x05 +#define CHIP_860 0x06 +#define CHIP_895 0x0c +#define CHIP_875 0x0f +#define CHIP_895A 0x12 +#define CHIP_875A 0x13 +#define CHIP_875J 0x8f -#define CHIP_810 0x01 -#define CHIP_820 0x02 -#define CHIP_825 0x03 -#define CHIP_815 0x04 -#define CHIP_810AP 0x05 -#define CHIP_860 0x06 -#define CHIP_895 0x0c -#define CHIP_875 0x0f -#define CHIP_895A 0x12 -#define CHIP_875A 0x13 -#define CHIP_875J 0x8f +#define NCR_SCNTL0_TRG 0x01 +#define NCR_SCNTL0_AAP 0x02 +#define NCR_SCNTL0_EPC 0x08 +#define NCR_SCNTL0_WATN 0x10 +#define NCR_SCNTL0_START 0x20 -#define NCR_SCNTL0_TRG 0x01 -#define NCR_SCNTL0_AAP 0x02 -#define NCR_SCNTL0_EPC 0x08 -#define NCR_SCNTL0_WATN 0x10 -#define NCR_SCNTL0_START 0x20 +#define NCR_SCNTL1_SST 0x01 +#define NCR_SCNTL1_IARB 0x02 +#define NCR_SCNTL1_AESP 0x04 +#define NCR_SCNTL1_RST 0x08 +#define NCR_SCNTL1_CON 0x10 +#define NCR_SCNTL1_DHP 0x20 +#define NCR_SCNTL1_ADB 0x40 +#define NCR_SCNTL1_EXC 0x80 -#define NCR_SCNTL1_SST 0x01 -#define NCR_SCNTL1_IARB 0x02 -#define NCR_SCNTL1_AESP 0x04 -#define NCR_SCNTL1_RST 0x08 -#define NCR_SCNTL1_CON 0x10 -#define NCR_SCNTL1_DHP 0x20 -#define NCR_SCNTL1_ADB 0x40 -#define NCR_SCNTL1_EXC 0x80 +#define NCR_SCNTL2_WSR 0x01 +#define NCR_SCNTL2_VUE0 0x02 +#define NCR_SCNTL2_VUE1 0x04 +#define NCR_SCNTL2_WSS 0x08 +#define NCR_SCNTL2_SLPHBEN 0x10 +#define NCR_SCNTL2_SLPMD 0x20 +#define NCR_SCNTL2_CHM 0x40 +#define NCR_SCNTL2_SDU 0x80 -#define NCR_SCNTL2_WSR 0x01 -#define NCR_SCNTL2_VUE0 0x02 -#define NCR_SCNTL2_VUE1 0x04 -#define NCR_SCNTL2_WSS 0x08 -#define NCR_SCNTL2_SLPHBEN 0x10 -#define NCR_SCNTL2_SLPMD 0x20 -#define NCR_SCNTL2_CHM 0x40 -#define NCR_SCNTL2_SDU 0x80 +#define NCR_ISTAT_DIP 0x01 +#define NCR_ISTAT_SIP 0x02 +#define NCR_ISTAT_INTF 0x04 +#define NCR_ISTAT_CON 0x08 +#define NCR_ISTAT_SEM 0x10 +#define NCR_ISTAT_SIGP 0x20 +#define NCR_ISTAT_SRST 0x40 +#define NCR_ISTAT_ABRT 0x80 -#define NCR_ISTAT_DIP 0x01 -#define NCR_ISTAT_SIP 0x02 -#define NCR_ISTAT_INTF 0x04 -#define NCR_ISTAT_CON 0x08 -#define NCR_ISTAT_SEM 0x10 -#define NCR_ISTAT_SIGP 0x20 -#define NCR_ISTAT_SRST 0x40 -#define NCR_ISTAT_ABRT 0x80 +#define NCR_SSTAT0_SDP0 0x01 +#define NCR_SSTAT0_RST 0x02 +#define NCR_SSTAT0_WOA 0x04 +#define NCR_SSTAT0_LOA 0x08 +#define NCR_SSTAT0_AIP 0x10 +#define NCR_SSTAT0_OLF 0x20 +#define NCR_SSTAT0_ORF 0x40 +#define NCR_SSTAT0_ILF 0x80 -#define NCR_SSTAT0_SDP0 0x01 -#define NCR_SSTAT0_RST 0x02 -#define NCR_SSTAT0_WOA 0x04 -#define NCR_SSTAT0_LOA 0x08 -#define NCR_SSTAT0_AIP 0x10 -#define NCR_SSTAT0_OLF 0x20 -#define NCR_SSTAT0_ORF 0x40 -#define NCR_SSTAT0_ILF 0x80 +#define NCR_SIST0_PAR 0x01 +#define NCR_SIST0_RST 0x02 +#define NCR_SIST0_UDC 0x04 +#define NCR_SIST0_SGE 0x08 +#define NCR_SIST0_RSL 0x10 +#define NCR_SIST0_SEL 0x20 +#define NCR_SIST0_CMP 0x40 +#define NCR_SIST0_MA 0x80 -#define NCR_SIST0_PAR 0x01 -#define NCR_SIST0_RST 0x02 -#define NCR_SIST0_UDC 0x04 -#define NCR_SIST0_SGE 0x08 -#define NCR_SIST0_RSL 0x10 -#define NCR_SIST0_SEL 0x20 -#define NCR_SIST0_CMP 0x40 -#define NCR_SIST0_MA 0x80 +#define NCR_SIST1_HTH 0x01 +#define NCR_SIST1_GEN 0x02 +#define NCR_SIST1_STO 0x04 +#define NCR_SIST1_SBMC 0x10 -#define NCR_SIST1_HTH 0x01 -#define NCR_SIST1_GEN 0x02 -#define NCR_SIST1_STO 0x04 -#define NCR_SIST1_SBMC 0x10 +#define NCR_SOCL_IO 0x01 +#define NCR_SOCL_CD 0x02 +#define NCR_SOCL_MSG 0x04 +#define NCR_SOCL_ATN 0x08 +#define NCR_SOCL_SEL 0x10 +#define NCR_SOCL_BSY 0x20 +#define NCR_SOCL_ACK 0x40 +#define NCR_SOCL_REQ 0x80 -#define NCR_SOCL_IO 0x01 -#define NCR_SOCL_CD 0x02 -#define NCR_SOCL_MSG 0x04 -#define NCR_SOCL_ATN 0x08 -#define NCR_SOCL_SEL 0x10 -#define NCR_SOCL_BSY 0x20 -#define NCR_SOCL_ACK 0x40 -#define NCR_SOCL_REQ 0x80 +#define NCR_DSTAT_IID 0x01 +#define NCR_DSTAT_SIR 0x04 +#define NCR_DSTAT_SSI 0x08 +#define NCR_DSTAT_ABRT 0x10 +#define NCR_DSTAT_BF 0x20 +#define NCR_DSTAT_MDPE 0x40 +#define NCR_DSTAT_DFE 0x80 -#define NCR_DSTAT_IID 0x01 -#define NCR_DSTAT_SIR 0x04 -#define NCR_DSTAT_SSI 0x08 -#define NCR_DSTAT_ABRT 0x10 -#define NCR_DSTAT_BF 0x20 -#define NCR_DSTAT_MDPE 0x40 -#define NCR_DSTAT_DFE 0x80 +#define NCR_DCNTL_COM 0x01 +#define NCR_DCNTL_IRQD 0x02 +#define NCR_DCNTL_STD 0x04 +#define NCR_DCNTL_IRQM 0x08 +#define NCR_DCNTL_SSM 0x10 +#define NCR_DCNTL_PFEN 0x20 +#define NCR_DCNTL_PFF 0x40 +#define NCR_DCNTL_CLSE 0x80 -#define NCR_DCNTL_COM 0x01 -#define NCR_DCNTL_IRQD 0x02 -#define NCR_DCNTL_STD 0x04 -#define NCR_DCNTL_IRQM 0x08 -#define NCR_DCNTL_SSM 0x10 -#define NCR_DCNTL_PFEN 0x20 -#define NCR_DCNTL_PFF 0x40 -#define NCR_DCNTL_CLSE 0x80 +#define NCR_DMODE_MAN 0x01 +#define NCR_DMODE_BOF 0x02 +#define NCR_DMODE_ERMP 0x04 +#define NCR_DMODE_ERL 0x08 +#define NCR_DMODE_DIOM 0x10 +#define NCR_DMODE_SIOM 0x20 -#define NCR_DMODE_MAN 0x01 -#define NCR_DMODE_BOF 0x02 -#define NCR_DMODE_ERMP 0x04 -#define NCR_DMODE_ERL 0x08 -#define NCR_DMODE_DIOM 0x10 -#define NCR_DMODE_SIOM 0x20 +#define NCR_CTEST2_DACK 0x01 +#define NCR_CTEST2_DREQ 0x02 +#define NCR_CTEST2_TEOP 0x04 +#define NCR_CTEST2_PCICIE 0x08 +#define NCR_CTEST2_CM 0x10 +#define NCR_CTEST2_CIO 0x20 +#define NCR_CTEST2_SIGP 0x40 +#define NCR_CTEST2_DDIR 0x80 -#define NCR_CTEST2_DACK 0x01 -#define NCR_CTEST2_DREQ 0x02 -#define NCR_CTEST2_TEOP 0x04 -#define NCR_CTEST2_PCICIE 0x08 -#define NCR_CTEST2_CM 0x10 -#define NCR_CTEST2_CIO 0x20 -#define NCR_CTEST2_SIGP 0x40 -#define NCR_CTEST2_DDIR 0x80 - -#define NCR_CTEST5_BL2 0x04 -#define NCR_CTEST5_DDIR 0x08 -#define NCR_CTEST5_MASR 0x10 -#define NCR_CTEST5_DFSN 0x20 -#define NCR_CTEST5_BBCK 0x40 -#define NCR_CTEST5_ADCK 0x80 +#define NCR_CTEST5_BL2 0x04 +#define NCR_CTEST5_DDIR 0x08 +#define NCR_CTEST5_MASR 0x10 +#define NCR_CTEST5_DFSN 0x20 +#define NCR_CTEST5_BBCK 0x40 +#define NCR_CTEST5_ADCK 0x80 /* Enable Response to Reselection */ -#define NCR_SCID_RRE 0x60 +#define NCR_SCID_RRE 0x60 -#define PHASE_DO 0 -#define PHASE_DI 1 -#define PHASE_CMD 2 -#define PHASE_ST 3 -#define PHASE_MO 6 -#define PHASE_MI 7 -#define PHASE_MASK 7 +#define PHASE_DO 0 +#define PHASE_DI 1 +#define PHASE_CMD 2 +#define PHASE_ST 3 +#define PHASE_MO 6 +#define PHASE_MI 7 +#define PHASE_MASK 7 /* Maximum length of MSG IN data. */ #define NCR_MAX_MSGIN_LEN 8 /* Flag set if this is a tagged command. */ -#define NCR_TAG_VALID (1 << 16) +#define NCR_TAG_VALID (1 << 16) -#define NCR_NVRAM_SIZE 2048 -#define NCR_BUF_SIZE 4096 +#define NCR_NVRAM_SIZE 2048 +#define NCR_BUF_SIZE 4096 typedef struct ncr53c8xx_request { uint32_t tag; uint32_t dma_len; uint8_t *dma_buf; uint32_t pending; - int out; + int out; } ncr53c8xx_request; -typedef enum -{ - SCSI_STATE_SEND_COMMAND, - SCSI_STATE_READ_DATA, - SCSI_STATE_WRITE_DATA, - SCSI_STATE_READ_STATUS, - SCSI_STATE_READ_MESSAGE, - SCSI_STATE_WRITE_MESSAGE +typedef enum { + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_READ_DATA, + SCSI_STATE_WRITE_DATA, + SCSI_STATE_READ_STATUS, + SCSI_STATE_READ_MESSAGE, + SCSI_STATE_WRITE_MESSAGE } scsi_state_t; typedef struct { - char *nvr_path; - uint8_t pci_slot; - uint8_t chip, wide; - int has_bios; - int BIOSBase; - rom_t bios; - int PCIBase; - int MMIOBase; + char *nvr_path; + uint8_t pci_slot; + uint8_t chip, wide; + int has_bios; + int BIOSBase; + rom_t bios; + int PCIBase; + int MMIOBase; mem_mapping_t mmio_mapping; - int RAMBase; + int RAMBase; mem_mapping_t ram_mapping; int carry; /* ??? Should this be an a visible register somewhere? */ int status; /* Action to take at the end of a MSG IN phase. 0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN. */ - int msg_action; - int msg_len; + int msg_action; + int msg_len; uint8_t msg[NCR_MAX_MSGIN_LEN]; uint8_t nvram[NCR_NVRAM_SIZE]; /* 24C16 EEPROM (16 Kbit) */ - void *i2c, *eeprom; - uint8_t ram[NCR_BUF_SIZE]; /* NCR 53C875 RAM (4 KB) */ + void *i2c, *eeprom; + uint8_t ram[NCR_BUF_SIZE]; /* NCR 53C875 RAM (4 KB) */ /* 0 if SCRIPTS are running or stopped. * 1 if a Wait Reselect instruction has been issued. * 2 if processing DMA from ncr53c8xx_execute_script. @@ -282,7 +280,7 @@ typedef struct { uint8_t gpcntl; uint8_t last_command; - int command_complete; + int command_complete; ncr53c8xx_request *current; int irq; @@ -296,14 +294,14 @@ typedef struct { uint32_t scratcha, scratchb, scratchc, scratchd; uint32_t scratche, scratchf, scratchg, scratchh; uint32_t scratchi, scratchj; - int last_level; - void *hba_private; + int last_level; + void *hba_private; uint32_t buffer_pos; - int32_t temp_buf_len; + int32_t temp_buf_len; uint8_t sstop; - uint8_t regop; + uint8_t regop; uint32_t adder; uint32_t bios_mask; @@ -317,30 +315,26 @@ typedef struct { #endif } ncr53c8xx_t; - #ifdef ENABLE_NCR53C8XX_LOG int ncr53c8xx_do_log = ENABLE_NCR53C8XX_LOG; - static void ncr53c8xx_log(const char *fmt, ...) { va_list ap; if (ncr53c8xx_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ncr53c8xx_log(fmt, ...) +# define ncr53c8xx_log(fmt, ...) #endif - -static uint8_t ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset); -static void ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val); - +static uint8_t ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset); +static void ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val); static __inline int32_t sextract32(uint32_t value, int start, int length) @@ -348,17 +342,15 @@ sextract32(uint32_t value, int start, int length) /* Note that this implementation relies on right shift of signed * integers being an arithmetic shift. */ - return ((int32_t)(value << (32 - length - start))) >> (32 - length); + return ((int32_t) (value << (32 - length - start))) >> (32 - length); } - static __inline int ncr53c8xx_irq_on_rsl(ncr53c8xx_t *dev) { return (dev->sien0 & NCR_SIST0_RSL) && (dev->scid & NCR_SCID_RRE); } - static void ncr53c8xx_soft_reset(ncr53c8xx_t *dev) { @@ -370,152 +362,147 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev) dev->carry = 0; dev->msg_action = 0; - dev->msg_len = 0; - dev->waiting = 0; - dev->dsa = 0; - dev->dnad = 0; - dev->dbc = 0; - dev->temp = 0; - dev->scratcha = 0; - dev->scratchb = 0; - dev->scratchc = 0; - dev->scratchd = 0; - dev->scratche = 0; - dev->scratchf = 0; - dev->scratchg = 0; - dev->scratchh = 0; - dev->scratchi = 0; - dev->scratchj = 0; - dev->istat = 0; - dev->dcmd = 0x40; - dev->dstat = NCR_DSTAT_DFE; - dev->dien = 0; - dev->sist0 = 0; - dev->sist1 = 0; - dev->sien0 = 0; - dev->sien1 = 0; - dev->mbox0 = 0; - dev->mbox1 = 0; - dev->dfifo = 0; - dev->ctest2 = NCR_CTEST2_DACK; - dev->ctest3 = 0; - dev->ctest4 = 0; - dev->ctest5 = 0; - dev->dsp = 0; - dev->dsps = 0; - dev->dmode = 0; - dev->dcntl = 0; - dev->scntl0 = 0xc0; - dev->scntl1 = 0; - dev->scntl2 = 0; + dev->msg_len = 0; + dev->waiting = 0; + dev->dsa = 0; + dev->dnad = 0; + dev->dbc = 0; + dev->temp = 0; + dev->scratcha = 0; + dev->scratchb = 0; + dev->scratchc = 0; + dev->scratchd = 0; + dev->scratche = 0; + dev->scratchf = 0; + dev->scratchg = 0; + dev->scratchh = 0; + dev->scratchi = 0; + dev->scratchj = 0; + dev->istat = 0; + dev->dcmd = 0x40; + dev->dstat = NCR_DSTAT_DFE; + dev->dien = 0; + dev->sist0 = 0; + dev->sist1 = 0; + dev->sien0 = 0; + dev->sien1 = 0; + dev->mbox0 = 0; + dev->mbox1 = 0; + dev->dfifo = 0; + dev->ctest2 = NCR_CTEST2_DACK; + dev->ctest3 = 0; + dev->ctest4 = 0; + dev->ctest5 = 0; + dev->dsp = 0; + dev->dsps = 0; + dev->dmode = 0; + dev->dcntl = 0; + dev->scntl0 = 0xc0; + dev->scntl1 = 0; + dev->scntl2 = 0; if (dev->wide) - dev->scntl3 = 8; + dev->scntl3 = 8; else - dev->scntl3 = 0; - dev->sstat0 = 0; - dev->sstat1 = 0; - dev->scid = HA_ID; - dev->sxfer = 0; - dev->socl = 0; - dev->sdid = 0; - dev->ssid = 0; - dev->stest1 = 0; - dev->stest2 = 0; - dev->stest3 = 0; - dev->sidl0 = 0; - dev->sidl1 = 0; - dev->stime0 = 0; - dev->stime0 = 1; - dev->respid0 = 0x80; - dev->respid1 = 0x00; - dev->sbr = 0; + dev->scntl3 = 0; + dev->sstat0 = 0; + dev->sstat1 = 0; + dev->scid = HA_ID; + dev->sxfer = 0; + dev->socl = 0; + dev->sdid = 0; + dev->ssid = 0; + dev->stest1 = 0; + dev->stest2 = 0; + dev->stest3 = 0; + dev->sidl0 = 0; + dev->sidl1 = 0; + dev->stime0 = 0; + dev->stime0 = 1; + dev->respid0 = 0x80; + dev->respid1 = 0x00; + dev->sbr = 0; dev->last_level = 0; - dev->gpreg = 0; - dev->slpar = 0; - dev->sstop = 1; - dev->gpcntl = 0x03; + dev->gpreg = 0; + dev->slpar = 0; + dev->sstop = 1; + dev->gpcntl = 0x03; if (dev->wide) { - /* This *IS* a wide SCSI controller, so reset all SCSI - devices. */ - for (i = 0; i < 16; i++) { + /* This *IS* a wide SCSI controller, so reset all SCSI + devices. */ + for (i = 0; i < 16; i++) { #ifdef USE_WDTR - dev->tr_set[i] = 0; + dev->tr_set[i] = 0; #endif - scsi_device_reset(&scsi_devices[dev->bus][i]); - } + scsi_device_reset(&scsi_devices[dev->bus][i]); + } } else { - /* This is *NOT* a wide SCSI controller, so do not touch - SCSI devices with ID's >= 8. */ - for (i = 0; i < 8; i++) { + /* This is *NOT* a wide SCSI controller, so do not touch + SCSI devices with ID's >= 8. */ + for (i = 0; i < 8; i++) { #ifdef USE_WDTR - dev->tr_set[i] = 0; + dev->tr_set[i] = 0; #endif - scsi_device_reset(&scsi_devices[dev->bus][i]); - } + scsi_device_reset(&scsi_devices[dev->bus][i]); + } } } - static void ncr53c8xx_read(ncr53c8xx_t *dev, uint32_t addr, uint8_t *buf, uint32_t len) { - uint32_t i = 0; + uint32_t i = 0; - ncr53c8xx_log("ncr53c8xx_read(): %08X-%08X, length %i\n", addr, (addr + len - 1), len); + ncr53c8xx_log("ncr53c8xx_read(): %08X-%08X, length %i\n", addr, (addr + len - 1), len); - if (dev->dmode & NCR_DMODE_SIOM) { - ncr53c8xx_log("NCR 810: Reading from I/O address %04X\n", (uint16_t) addr); - for (i = 0; i < len; i++) - buf[i] = inb((uint16_t) (addr + i)); - } else { - ncr53c8xx_log("NCR 810: Reading from memory address %08X\n", addr); - dma_bm_read(addr, buf, len, 4); - } + if (dev->dmode & NCR_DMODE_SIOM) { + ncr53c8xx_log("NCR 810: Reading from I/O address %04X\n", (uint16_t) addr); + for (i = 0; i < len; i++) + buf[i] = inb((uint16_t) (addr + i)); + } else { + ncr53c8xx_log("NCR 810: Reading from memory address %08X\n", addr); + dma_bm_read(addr, buf, len, 4); + } } - static void ncr53c8xx_write(ncr53c8xx_t *dev, uint32_t addr, uint8_t *buf, uint32_t len) { - uint32_t i = 0; + uint32_t i = 0; - ncr53c8xx_log("ncr53c8xx_write(): %08X-%08X, length %i\n", addr, (addr + len - 1), len); + ncr53c8xx_log("ncr53c8xx_write(): %08X-%08X, length %i\n", addr, (addr + len - 1), len); - if (dev->dmode & NCR_DMODE_DIOM) { - ncr53c8xx_log("NCR 810: Writing to I/O address %04X\n", (uint16_t) addr); - for (i = 0; i < len; i++) - outb((uint16_t) (addr + i), buf[i]); - } else { - ncr53c8xx_log("NCR 810: Writing to memory address %08X\n", addr); - dma_bm_write(addr, buf, len, 4); - } + if (dev->dmode & NCR_DMODE_DIOM) { + ncr53c8xx_log("NCR 810: Writing to I/O address %04X\n", (uint16_t) addr); + for (i = 0; i < len; i++) + outb((uint16_t) (addr + i), buf[i]); + } else { + ncr53c8xx_log("NCR 810: Writing to memory address %08X\n", addr); + dma_bm_write(addr, buf, len, 4); + } } - static __inline uint32_t read_dword(ncr53c8xx_t *dev, uint32_t addr) { uint32_t buf; ncr53c8xx_log("Reading the next DWORD from memory (%08X)...\n", addr); - dma_bm_read(addr, (uint8_t *)&buf, 4, 4); + dma_bm_read(addr, (uint8_t *) &buf, 4, 4); return buf; } - -static -void do_irq(ncr53c8xx_t *dev, int level) +static void +do_irq(ncr53c8xx_t *dev, int level) { if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); - ncr53c8xx_log("Raising IRQ...\n"); + pci_set_irq(dev->pci_slot, PCI_INTA); + ncr53c8xx_log("Raising IRQ...\n"); } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); - ncr53c8xx_log("Lowering IRQ...\n"); + pci_clear_irq(dev->pci_slot, PCI_INTA); + ncr53c8xx_log("Lowering IRQ...\n"); } } - static void ncr53c8xx_update_irq(ncr53c8xx_t *dev) { @@ -546,13 +533,12 @@ ncr53c8xx_update_irq(ncr53c8xx_t *dev) if (level != dev->last_level) { ncr53c8xx_log("Update IRQ level %d dstat %02x sist %02x%02x\n", - level, dev->dstat, dev->sist1, dev->sist0); + level, dev->dstat, dev->sist1, dev->sist0); dev->last_level = level; - do_irq(dev, level); /* Only do something with the IRQ if the new level differs from the previous one. */ + do_irq(dev, level); /* Only do something with the IRQ if the new level differs from the previous one. */ } } - /* Stop SCRIPTS execution and raise a SCSI interrupt. */ static void ncr53c8xx_script_scsi_interrupt(ncr53c8xx_t *dev, int stat0, int stat1) @@ -561,7 +547,7 @@ ncr53c8xx_script_scsi_interrupt(ncr53c8xx_t *dev, int stat0, int stat1) uint32_t mask1; ncr53c8xx_log("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n", - stat1, stat0, dev->sist1, dev->sist0); + stat1, stat0, dev->sist1, dev->sist0); dev->sist0 |= stat0; dev->sist1 |= stat1; /* Stop processor on fatal or unmasked interrupt. As a special hack @@ -571,14 +557,13 @@ ncr53c8xx_script_scsi_interrupt(ncr53c8xx_t *dev, int stat0, int stat1) mask1 = dev->sien1 | ~(NCR_SIST1_GEN | NCR_SIST1_HTH); mask1 &= ~NCR_SIST1_STO; if ((dev->sist0 & mask0) || (dev->sist1 & mask1)) { - ncr53c8xx_log("NCR 810: IRQ-mandated stop\n"); - dev->sstop = 1; - timer_stop(&dev->timer); + ncr53c8xx_log("NCR 810: IRQ-mandated stop\n"); + dev->sstop = 1; + timer_stop(&dev->timer); } ncr53c8xx_update_irq(dev); } - /* Stop SCRIPTS execution and raise a DMA interrupt. */ static void ncr53c8xx_script_dma_interrupt(ncr53c8xx_t *dev, int stat) @@ -590,14 +575,12 @@ ncr53c8xx_script_dma_interrupt(ncr53c8xx_t *dev, int stat) timer_stop(&dev->timer); } - static __inline void ncr53c8xx_set_phase(ncr53c8xx_t *dev, int phase) { dev->sstat1 = (dev->sstat1 & ~PHASE_MASK) | phase; } - static void ncr53c8xx_bad_phase(ncr53c8xx_t *dev, int out, int new_phase) { @@ -609,7 +592,6 @@ ncr53c8xx_bad_phase(ncr53c8xx_t *dev, int out, int new_phase) ncr53c8xx_set_phase(dev, new_phase); } - static void ncr53c8xx_disconnect(ncr53c8xx_t *dev) { @@ -619,12 +601,11 @@ ncr53c8xx_disconnect(ncr53c8xx_t *dev) dev->scntl1 &= ~NCR_SCNTL1_CON; dev->sstat1 &= ~PHASE_MASK; - if (dev->dcmd & 0x01) /* Select with ATN */ - dev->sstat1 |= 0x07; + if (dev->dcmd & 0x01) /* Select with ATN */ + dev->sstat1 |= 0x07; scsi_device_identify(sd, SCSI_LUN_USE_CDB); } - static void ncr53c8xx_bad_selection(ncr53c8xx_t *dev, uint32_t id) { @@ -633,51 +614,49 @@ ncr53c8xx_bad_selection(ncr53c8xx_t *dev, uint32_t id) ncr53c8xx_disconnect(dev); } - /* Callback to indicate that the SCSI layer has completed a command. */ static void ncr53c8xx_command_complete(void *priv, uint32_t status) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)priv; - int out; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; + int out; out = (dev->sstat1 & PHASE_MASK) == PHASE_DO; - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Command complete status=%d\n", dev->current->tag, dev->current_lun, dev->last_command, (int)status); - dev->status = status; + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Command complete status=%d\n", dev->current->tag, dev->current_lun, dev->last_command, (int) status); + dev->status = status; dev->command_complete = 2; if (dev->waiting && dev->dbc != 0) { - /* Raise phase mismatch for short transfers. */ - ncr53c8xx_bad_phase(dev, out, PHASE_ST); + /* Raise phase mismatch for short transfers. */ + ncr53c8xx_bad_phase(dev, out, PHASE_ST); } else - ncr53c8xx_set_phase(dev, PHASE_ST); + ncr53c8xx_set_phase(dev, PHASE_ST); dev->sstop = 0; } - static void ncr53c8xx_do_dma(ncr53c8xx_t *dev, int out, uint8_t id) { uint32_t addr, tdbc; - int count; + int count; scsi_device_t *sd = &scsi_devices[dev->bus][id]; if ((!scsi_device_present(sd))) { - ncr53c8xx_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; + ncr53c8xx_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; } if (!dev->current->dma_len) { - /* Wait until data is available. */ - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DMA no data available\n", id, dev->current_lun, dev->last_command); - return; + /* Wait until data is available. */ + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DMA no data available\n", id, dev->current_lun, dev->last_command); + return; } /* Make sure count is never bigger than buffer_length. */ count = tdbc = dev->dbc; if (count > dev->temp_buf_len) - count = dev->temp_buf_len; + count = dev->temp_buf_len; addr = dev->dnad; @@ -686,45 +665,43 @@ ncr53c8xx_do_dma(ncr53c8xx_t *dev, int out, uint8_t id) dev->dbc -= count; if (out) - ncr53c8xx_read(dev, addr, sd->sc->temp_buffer + dev->buffer_pos, count); + ncr53c8xx_read(dev, addr, sd->sc->temp_buffer + dev->buffer_pos, count); else { #ifdef ENABLE_NCR53C8XX_LOG - if (!dev->buffer_pos) - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command); + if (!dev->buffer_pos) + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command); #endif - ncr53c8xx_write(dev, addr, sd->sc->temp_buffer + dev->buffer_pos, count); + ncr53c8xx_write(dev, addr, sd->sc->temp_buffer + dev->buffer_pos, count); } dev->temp_buf_len -= count; dev->buffer_pos += count; if (dev->temp_buf_len <= 0) { - scsi_device_command_phase1(&scsi_devices[dev->bus][id]); + scsi_device_command_phase1(&scsi_devices[dev->bus][id]); #ifdef ENABLE_NCR53C8XX_LOG - if (out) - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command); + if (out) + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command); #endif - ncr53c8xx_command_complete(dev, sd->status); + ncr53c8xx_command_complete(dev, sd->status); } else { - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Resume SCRIPTS\n", id, dev->current_lun, dev->last_command); - dev->sstop = 0; + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Resume SCRIPTS\n", id, dev->current_lun, dev->last_command); + dev->sstop = 0; } } - /* Queue a byte for a MSG IN phase. */ static void ncr53c8xx_add_msg_byte(ncr53c8xx_t *dev, uint8_t data) { if (dev->msg_len >= NCR_MAX_MSGIN_LEN) - ncr53c8xx_log("MSG IN data too long\n"); + ncr53c8xx_log("MSG IN data too long\n"); else { - ncr53c8xx_log("MSG IN 0x%02x\n", data); - dev->msg[dev->msg_len++] = data; + ncr53c8xx_log("MSG IN 0x%02x\n", data); + dev->msg[dev->msg_len++] = data; } } - static void ncr53c8xx_timer_on(ncr53c8xx_t *dev, scsi_device_t *sd, double p) { @@ -736,30 +713,29 @@ ncr53c8xx_timer_on(ncr53c8xx_t *dev, scsi_device_t *sd, double p) timer_on_auto(&dev->timer, period + 40.0); } - static int ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id) { scsi_device_t *sd; - uint8_t buf[12]; + uint8_t buf[12]; memset(buf, 0, 12); dma_bm_read(dev->dnad, buf, MIN(12, dev->dbc), 4); if (dev->dbc > 12) { - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: CDB length %i too big\n", id, dev->current_lun, buf[0], dev->dbc); - dev->dbc = 12; + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: CDB length %i too big\n", id, dev->current_lun, buf[0], dev->dbc); + dev->dbc = 12; } - dev->sfbr = buf[0]; + dev->sfbr = buf[0]; dev->command_complete = 0; sd = &scsi_devices[dev->bus][id]; if (!scsi_device_present(sd) || (dev->current_lun > 0)) { - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]); - ncr53c8xx_bad_selection(dev, id); - return 0; + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]); + ncr53c8xx_bad_selection(dev, id); + return 0; } - dev->current = (ncr53c8xx_request*)malloc(sizeof(ncr53c8xx_request)); + dev->current = (ncr53c8xx_request *) malloc(sizeof(ncr53c8xx_request)); dev->current->tag = id; sd->buffer_length = -1; @@ -769,47 +745,46 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id) /* Make sure bits 5-7 of the CDB have the correct LUN. */ if ((buf[1] & 0xe0) != (dev->current_lun << 5)) - buf[1] = (buf[1] & 0x1f) | (dev->current_lun << 5); + buf[1] = (buf[1] & 0x1f) | (dev->current_lun << 5); scsi_device_command_phase0(&scsi_devices[dev->bus][dev->current->tag], buf); - dev->hba_private = (void *)dev->current; + dev->hba_private = (void *) dev->current; - dev->waiting = 0; + dev->waiting = 0; dev->buffer_pos = 0; dev->temp_buf_len = sd->buffer_length; if (sd->buffer_length > 0) { - /* This should be set to the underlying device's buffer by command phase 0. */ - dev->current->dma_len = sd->buffer_length; + /* This should be set to the underlying device's buffer by command phase 0. */ + dev->current->dma_len = sd->buffer_length; } if ((sd->phase == SCSI_PHASE_DATA_IN) && (sd->buffer_length > 0)) { - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]); - ncr53c8xx_set_phase(dev, PHASE_DI); - ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag])); - return 1; + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]); + ncr53c8xx_set_phase(dev, PHASE_DI); + ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag])); + return 1; } else if ((sd->phase == SCSI_PHASE_DATA_OUT) && (sd->buffer_length > 0)) { - ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]); - ncr53c8xx_set_phase(dev, PHASE_DO); - ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag])); - return 1; + ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]); + ncr53c8xx_set_phase(dev, PHASE_DO); + ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag])); + return 1; } else { - ncr53c8xx_command_complete(dev, sd->status); - return 0; + ncr53c8xx_command_complete(dev, sd->status); + return 0; } } - static void ncr53c8xx_do_status(ncr53c8xx_t *dev) { uint8_t status; ncr53c8xx_log("Get status len=%d status=%d\n", dev->dbc, dev->status); if (dev->dbc != 1) - ncr53c8xx_log("Bad Status move\n"); - dev->dbc = 1; - status = dev->status; + ncr53c8xx_log("Bad Status move\n"); + dev->dbc = 1; + status = dev->status; dev->sfbr = status; ncr53c8xx_write(dev, dev->dnad, &status, 1); ncr53c8xx_set_phase(dev, PHASE_MI); @@ -817,7 +792,6 @@ ncr53c8xx_do_status(ncr53c8xx_t *dev) ncr53c8xx_add_msg_byte(dev, 0); /* COMMAND COMPLETE */ } - #ifdef USE_WDTR static void ncr53c8xx_do_wdtr(ncr53c8xx_t *dev, int exponent) @@ -825,55 +799,53 @@ ncr53c8xx_do_wdtr(ncr53c8xx_t *dev, int exponent) ncr53c8xx_log("Target-initiated WDTR (%08X)\n", dev); ncr53c8xx_set_phase(dev, PHASE_MI); dev->msg_action = 4; - ncr53c8xx_add_msg_byte(dev, 0x01); /* EXTENDED MESSAGE */ - ncr53c8xx_add_msg_byte(dev, 0x02); /* EXTENDED MESSAGE LENGTH */ - ncr53c8xx_add_msg_byte(dev, 0x03); /* WIDE DATA TRANSFER REQUEST */ - ncr53c8xx_add_msg_byte(dev, exponent); /* TRANSFER WIDTH EXPONENT (16-bit) */ + ncr53c8xx_add_msg_byte(dev, 0x01); /* EXTENDED MESSAGE */ + ncr53c8xx_add_msg_byte(dev, 0x02); /* EXTENDED MESSAGE LENGTH */ + ncr53c8xx_add_msg_byte(dev, 0x03); /* WIDE DATA TRANSFER REQUEST */ + ncr53c8xx_add_msg_byte(dev, exponent); /* TRANSFER WIDTH EXPONENT (16-bit) */ } #endif - static void ncr53c8xx_do_msgin(ncr53c8xx_t *dev) { uint32_t len; ncr53c8xx_log("Message in len=%d/%d\n", dev->dbc, dev->msg_len); dev->sfbr = dev->msg[0]; - len = dev->msg_len; + len = dev->msg_len; if (len > dev->dbc) - len = dev->dbc; + len = dev->dbc; ncr53c8xx_write(dev, dev->dnad, dev->msg, len); /* Linux drivers rely on the last byte being in the SIDL. */ dev->sidl0 = dev->msg[len - 1]; dev->msg_len -= len; if (dev->msg_len) - memmove(dev->msg, dev->msg + len, dev->msg_len); - else { - /* ??? Check if ATN (not yet implemented) is asserted and maybe - switch to PHASE_MO. */ - switch (dev->msg_action) { - case 0: - ncr53c8xx_set_phase(dev, PHASE_CMD); - break; - case 1: - ncr53c8xx_disconnect(dev); - break; - case 2: - ncr53c8xx_set_phase(dev, PHASE_DO); - break; - case 3: - ncr53c8xx_set_phase(dev, PHASE_DI); - break; - case 4: - ncr53c8xx_set_phase(dev, PHASE_MO); - break; - default: - abort(); - } + memmove(dev->msg, dev->msg + len, dev->msg_len); + else { + /* ??? Check if ATN (not yet implemented) is asserted and maybe + switch to PHASE_MO. */ + switch (dev->msg_action) { + case 0: + ncr53c8xx_set_phase(dev, PHASE_CMD); + break; + case 1: + ncr53c8xx_disconnect(dev); + break; + case 2: + ncr53c8xx_set_phase(dev, PHASE_DO); + break; + case 3: + ncr53c8xx_set_phase(dev, PHASE_DI); + break; + case 4: + ncr53c8xx_set_phase(dev, PHASE_MO); + break; + default: + abort(); + } } } - /* Read the next byte during a MSGOUT phase. */ static uint8_t ncr53c8xx_get_msgbyte(ncr53c8xx_t *dev) @@ -885,16 +857,14 @@ ncr53c8xx_get_msgbyte(ncr53c8xx_t *dev) return data; } - /* Skip the next n bytes during a MSGOUT phase. */ static void ncr53c8xx_skip_msgbytes(ncr53c8xx_t *dev, unsigned int n) { dev->dnad += n; - dev->dbc -= n; + dev->dbc -= n; } - static void ncr53c8xx_bad_message(ncr53c8xx_t *dev, uint8_t msg) { @@ -904,12 +874,11 @@ ncr53c8xx_bad_message(ncr53c8xx_t *dev, uint8_t msg) dev->msg_action = 0; } - static void ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) { uint8_t msg; - int len, arg; + int len, arg; #ifdef ENABLE_NCR53C8XX_LOG uint32_t current_tag; #endif @@ -923,120 +892,118 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) ncr53c8xx_log("MSG out len=%d\n", dev->dbc); while (dev->dbc) { - msg = ncr53c8xx_get_msgbyte(dev); - dev->sfbr = msg; + msg = ncr53c8xx_get_msgbyte(dev); + dev->sfbr = msg; - switch (msg) { - case 0x04: - ncr53c8xx_log("MSG: Disconnect\n"); - ncr53c8xx_disconnect(dev); - break; - case 0x08: - ncr53c8xx_log("MSG: No Operation\n"); - ncr53c8xx_set_phase(dev, PHASE_CMD); - break; - case 0x01: - len = ncr53c8xx_get_msgbyte(dev); - msg = ncr53c8xx_get_msgbyte(dev); - arg = ncr53c8xx_get_msgbyte(dev); - (void) len; /* avoid a warning about unused variable*/ - ncr53c8xx_log("Extended message 0x%x (len %d)\n", msg, len); - switch (msg) { - case 1: - ncr53c8xx_log("SDTR (ignored)\n"); - ncr53c8xx_skip_msgbytes(dev, 1); - break; - case 3: - ncr53c8xx_log("WDTR (ignored)\n"); + switch (msg) { + case 0x04: + ncr53c8xx_log("MSG: Disconnect\n"); + ncr53c8xx_disconnect(dev); + break; + case 0x08: + ncr53c8xx_log("MSG: No Operation\n"); + ncr53c8xx_set_phase(dev, PHASE_CMD); + break; + case 0x01: + len = ncr53c8xx_get_msgbyte(dev); + msg = ncr53c8xx_get_msgbyte(dev); + arg = ncr53c8xx_get_msgbyte(dev); + (void) len; /* avoid a warning about unused variable*/ + ncr53c8xx_log("Extended message 0x%x (len %d)\n", msg, len); + switch (msg) { + case 1: + ncr53c8xx_log("SDTR (ignored)\n"); + ncr53c8xx_skip_msgbytes(dev, 1); + break; + case 3: + ncr53c8xx_log("WDTR (ignored)\n"); #ifdef USE_WDTR - dev->tr_set[dev->sdid] = 1; + dev->tr_set[dev->sdid] = 1; #endif - if (arg > 0x01) { - ncr53c8xx_bad_message(dev, msg); - return; - } - ncr53c8xx_set_phase(dev, PHASE_CMD); - break; - case 5: - ncr53c8xx_log("PPR (ignored)\n"); - ncr53c8xx_skip_msgbytes(dev, 4); - break; - default: - ncr53c8xx_bad_message(dev, msg); - return; - } - break; - case 0x20: /* SIMPLE queue */ - id |= ncr53c8xx_get_msgbyte(dev) | NCR_TAG_VALID; - ncr53c8xx_log("SIMPLE queue tag=0x%x\n", id & 0xff); - break; - case 0x21: /* HEAD of queue */ - ncr53c8xx_log("HEAD queue not implemented\n"); - id |= ncr53c8xx_get_msgbyte(dev) | NCR_TAG_VALID; - break; - case 0x22: /* ORDERED queue */ - ncr53c8xx_log("ORDERED queue not implemented\n"); - id |= ncr53c8xx_get_msgbyte(dev) | NCR_TAG_VALID; - break; - case 0x0d: - /* The ABORT TAG message clears the current I/O process only. */ - ncr53c8xx_log("MSG: Abort Tag\n"); - scsi_device_command_stop(sd); - ncr53c8xx_disconnect(dev); - break; - case 0x0c: - /* BUS DEVICE RESET message, reset wide transfer request. */ + if (arg > 0x01) { + ncr53c8xx_bad_message(dev, msg); + return; + } + ncr53c8xx_set_phase(dev, PHASE_CMD); + break; + case 5: + ncr53c8xx_log("PPR (ignored)\n"); + ncr53c8xx_skip_msgbytes(dev, 4); + break; + default: + ncr53c8xx_bad_message(dev, msg); + return; + } + break; + case 0x20: /* SIMPLE queue */ + id |= ncr53c8xx_get_msgbyte(dev) | NCR_TAG_VALID; + ncr53c8xx_log("SIMPLE queue tag=0x%x\n", id & 0xff); + break; + case 0x21: /* HEAD of queue */ + ncr53c8xx_log("HEAD queue not implemented\n"); + id |= ncr53c8xx_get_msgbyte(dev) | NCR_TAG_VALID; + break; + case 0x22: /* ORDERED queue */ + ncr53c8xx_log("ORDERED queue not implemented\n"); + id |= ncr53c8xx_get_msgbyte(dev) | NCR_TAG_VALID; + break; + case 0x0d: + /* The ABORT TAG message clears the current I/O process only. */ + ncr53c8xx_log("MSG: Abort Tag\n"); + scsi_device_command_stop(sd); + ncr53c8xx_disconnect(dev); + break; + case 0x0c: + /* BUS DEVICE RESET message, reset wide transfer request. */ #ifdef USE_WDTR - dev->tr_set[dev->sdid] = 0; + dev->tr_set[dev->sdid] = 0; #endif - /* FALLTHROUGH */ - case 0x06: - case 0x0e: - /* clear the current I/O process */ - scsi_device_command_stop(sd); - ncr53c8xx_disconnect(dev); - break; - default: - if ((msg & 0x80) == 0) { - ncr53c8xx_bad_message(dev, msg); - return; - } else { - /* 0x80 to 0xff are IDENTIFY messages. */ - ncr53c8xx_log("MSG: Identify\n"); - dev->current_lun = msg & 7; - scsi_device_identify(sd, msg & 7); - ncr53c8xx_log("Select LUN %d\n", dev->current_lun); + /* FALLTHROUGH */ + case 0x06: + case 0x0e: + /* clear the current I/O process */ + scsi_device_command_stop(sd); + ncr53c8xx_disconnect(dev); + break; + default: + if ((msg & 0x80) == 0) { + ncr53c8xx_bad_message(dev, msg); + return; + } else { + /* 0x80 to 0xff are IDENTIFY messages. */ + ncr53c8xx_log("MSG: Identify\n"); + dev->current_lun = msg & 7; + scsi_device_identify(sd, msg & 7); + ncr53c8xx_log("Select LUN %d\n", dev->current_lun); #ifdef USE_WDTR - if ((dev->chip == CHIP_875) && !dev->tr_set[dev->sdid]) - ncr53c8xx_do_wdtr(dev, 0x01); - else + if ((dev->chip == CHIP_875) && !dev->tr_set[dev->sdid]) + ncr53c8xx_do_wdtr(dev, 0x01); + else #endif - ncr53c8xx_set_phase(dev, PHASE_CMD); - } - break; - } + ncr53c8xx_set_phase(dev, PHASE_CMD); + } + break; + } } } - static void ncr53c8xx_memcpy(ncr53c8xx_t *dev, uint32_t dest, uint32_t src, int count) { - int n; + int n; uint8_t buf[NCR_BUF_SIZE]; ncr53c8xx_log("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count); while (count) { - n = (count > NCR_BUF_SIZE) ? NCR_BUF_SIZE : count; - ncr53c8xx_read(dev, src, buf, n); - ncr53c8xx_write(dev, dest, buf, n); - src += n; - dest += n; - count -= n; + n = (count > NCR_BUF_SIZE) ? NCR_BUF_SIZE : count; + ncr53c8xx_read(dev, src, buf, n); + ncr53c8xx_write(dev, dest, buf, n); + src += n; + dest += n; + count -= n; } } - static void ncr53c8xx_process_script(ncr53c8xx_t *dev) { @@ -1053,15 +1020,15 @@ again: insn_processed++; insn = read_dword(dev, dev->dsp); if (!insn) { - /* If we receive an empty opcode increment the DSP by 4 bytes - instead of 8 and execute the next opcode at that location */ - dev->dsp += 4; - if (insn_processed < 100) - goto again; - else { - timer_on_auto(&dev->timer, 10.0); - return; - } + /* If we receive an empty opcode increment the DSP by 4 bytes + instead of 8 and execute the next opcode at that location */ + dev->dsp += 4; + if (insn_processed < 100) + goto again; + else { + timer_on_auto(&dev->timer, 10.0); + return; + } } addr = read_dword(dev, dev->dsp + 4); ncr53c8xx_log("SCRIPTS dsp=%08x opcode %08x arg %08x\n", dev->dsp, insn, addr); @@ -1070,357 +1037,357 @@ again: dev->dsp += 8; switch (insn >> 30) { - case 0: /* Block move. */ - ncr53c8xx_log("00: Block move\n"); - if (dev->sist1 & NCR_SIST1_STO) { - ncr53c8xx_log("Delayed select timeout\n"); - dev->sstop = 1; - break; - } - ncr53c8xx_log("Block Move DBC=%d\n", dev->dbc); - dev->dbc = insn & 0xffffff; - ncr53c8xx_log("Block Move DBC=%d now\n", dev->dbc); - /* ??? Set ESA. */ - if (insn & (1 << 29)) { - /* Indirect addressing. */ - /* Should this respect SIOM? */ - addr = read_dword(dev, addr); - ncr53c8xx_log("Indirect Block Move address: %08X\n", addr); - } else if (insn & (1 << 28)) { - /* Table indirect addressing. */ + case 0: /* Block move. */ + ncr53c8xx_log("00: Block move\n"); + if (dev->sist1 & NCR_SIST1_STO) { + ncr53c8xx_log("Delayed select timeout\n"); + dev->sstop = 1; + break; + } + ncr53c8xx_log("Block Move DBC=%d\n", dev->dbc); + dev->dbc = insn & 0xffffff; + ncr53c8xx_log("Block Move DBC=%d now\n", dev->dbc); + /* ??? Set ESA. */ + if (insn & (1 << 29)) { + /* Indirect addressing. */ + /* Should this respect SIOM? */ + addr = read_dword(dev, addr); + ncr53c8xx_log("Indirect Block Move address: %08X\n", addr); + } else if (insn & (1 << 28)) { + /* Table indirect addressing. */ - /* 32-bit Table indirect */ - offset = sextract32(addr, 0, 24); - dma_bm_read(dev->dsa + offset, (uint8_t *)buf, 8, 4); - /* byte count is stored in bits 0:23 only */ - dev->dbc = buf[0] & 0xffffff; - addr = buf[1]; + /* 32-bit Table indirect */ + offset = sextract32(addr, 0, 24); + dma_bm_read(dev->dsa + offset, (uint8_t *) buf, 8, 4); + /* byte count is stored in bits 0:23 only */ + dev->dbc = buf[0] & 0xffffff; + addr = buf[1]; - /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of - * table, bits [31:24] */ - } - if ((dev->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) { - ncr53c8xx_log("Wrong phase got %d expected %d\n", - dev->sstat1 & PHASE_MASK, (insn >> 24) & 7); - ncr53c8xx_script_scsi_interrupt(dev, NCR_SIST0_MA, 0); - break; - } - dev->dnad = addr; - switch (dev->sstat1 & 0x7) { - case PHASE_DO: - ncr53c8xx_log("Data Out Phase\n"); - dev->waiting = 0; - ncr53c8xx_do_dma(dev, 1, dev->sdid); - break; - case PHASE_DI: - ncr53c8xx_log("Data In Phase\n"); - dev->waiting = 0; - ncr53c8xx_do_dma(dev, 0, dev->sdid); - break; - case PHASE_CMD: - ncr53c8xx_log("Command Phase\n"); - c = ncr53c8xx_do_command(dev, dev->sdid); + /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of + * table, bits [31:24] */ + } + if ((dev->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) { + ncr53c8xx_log("Wrong phase got %d expected %d\n", + dev->sstat1 & PHASE_MASK, (insn >> 24) & 7); + ncr53c8xx_script_scsi_interrupt(dev, NCR_SIST0_MA, 0); + break; + } + dev->dnad = addr; + switch (dev->sstat1 & 0x7) { + case PHASE_DO: + ncr53c8xx_log("Data Out Phase\n"); + dev->waiting = 0; + ncr53c8xx_do_dma(dev, 1, dev->sdid); + break; + case PHASE_DI: + ncr53c8xx_log("Data In Phase\n"); + dev->waiting = 0; + ncr53c8xx_do_dma(dev, 0, dev->sdid); + break; + case PHASE_CMD: + ncr53c8xx_log("Command Phase\n"); + c = ncr53c8xx_do_command(dev, dev->sdid); - if (!c || dev->sstop || dev->waiting || ((dev->sstat1 & 0x7) == PHASE_ST)) - break; + if (!c || dev->sstop || dev->waiting || ((dev->sstat1 & 0x7) == PHASE_ST)) + break; - dev->dfifo = dev->dbc & 0xff; - dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); + dev->dfifo = dev->dbc & 0xff; + dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); - if (dev->dcntl & NCR_DCNTL_SSM) - ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SSI); - return; - case PHASE_ST: - ncr53c8xx_log("Status Phase\n"); - ncr53c8xx_do_status(dev); - break; - case PHASE_MO: - ncr53c8xx_log("MSG Out Phase\n"); - ncr53c8xx_do_msgout(dev, dev->sdid); - break; - case PHASE_MI: - ncr53c8xx_log("MSG In Phase\n"); - ncr53c8xx_do_msgin(dev); - break; - default: - ncr53c8xx_log("Unimplemented phase %d\n", dev->sstat1 & PHASE_MASK); - } - dev->dfifo = dev->dbc & 0xff; - dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); - break; + if (dev->dcntl & NCR_DCNTL_SSM) + ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SSI); + return; + case PHASE_ST: + ncr53c8xx_log("Status Phase\n"); + ncr53c8xx_do_status(dev); + break; + case PHASE_MO: + ncr53c8xx_log("MSG Out Phase\n"); + ncr53c8xx_do_msgout(dev, dev->sdid); + break; + case PHASE_MI: + ncr53c8xx_log("MSG In Phase\n"); + ncr53c8xx_do_msgin(dev); + break; + default: + ncr53c8xx_log("Unimplemented phase %d\n", dev->sstat1 & PHASE_MASK); + } + dev->dfifo = dev->dbc & 0xff; + dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); + break; - case 1: /* IO or Read/Write instruction. */ - ncr53c8xx_log("01: I/O or Read/Write instruction\n"); - opcode = (insn >> 27) & 7; - if (opcode < 5) { - if (insn & (1 << 25)) - id = read_dword(dev, dev->dsa + sextract32(insn, 0, 24)); - else - id = insn; - id = (id >> 16) & 0xf; - if (insn & (1 << 26)) - addr = dev->dsp + sextract32(addr, 0, 24); - dev->dnad = addr; - switch (opcode) { - case 0: /* Select */ - dev->sdid = id; - if (dev->scntl1 & NCR_SCNTL1_CON) { - ncr53c8xx_log("Already reselected, jumping to alternative address\n"); - dev->dsp = dev->dnad; - break; - } - dev->sstat0 |= NCR_SSTAT0_WOA; - dev->scntl1 &= ~NCR_SCNTL1_IARB; - if (!scsi_device_present(&scsi_devices[dev->bus][id])) { - ncr53c8xx_bad_selection(dev, id); - break; - } - ncr53c8xx_log("Selected target %d%s\n", - id, insn & (1 << 24) ? " ATN" : ""); - dev->scntl1 |= NCR_SCNTL1_CON; - if (insn & (1 << 24)) - dev->socl |= NCR_SOCL_ATN; - ncr53c8xx_set_phase(dev, PHASE_MO); - dev->waiting = 0; - break; - case 1: /* Disconnect */ - ncr53c8xx_log("Wait Disconnect\n"); - dev->scntl1 &= ~NCR_SCNTL1_CON; - break; - case 2: /* Wait Reselect */ - ncr53c8xx_log("Wait Reselect\n"); - if (dev->istat & NCR_ISTAT_SIGP) - dev->dsp = dev->dnad; /* If SIGP is set, this command causes an immediate jump to DNAD. */ - else { - if (!ncr53c8xx_irq_on_rsl(dev)) - dev->waiting = 1; - } - break; - case 3: /* Set */ - ncr53c8xx_log("Set%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", - insn & (1 << 6) ? " ACK" : "", - insn & (1 << 9) ? " TM" : "", - insn & (1 << 10) ? " CC" : ""); - if (insn & (1 << 3)) { - dev->socl |= NCR_SOCL_ATN; - ncr53c8xx_set_phase(dev, PHASE_MO); - } - if (insn & (1 << 9)) - ncr53c8xx_log("Target mode not implemented\n"); - if (insn & (1 << 10)) - dev->carry = 1; - break; - case 4: /* Clear */ - ncr53c8xx_log("Clear%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", - insn & (1 << 6) ? " ACK" : "", - insn & (1 << 9) ? " TM" : "", - insn & (1 << 10) ? " CC" : ""); - if (insn & (1 << 3)) - dev->socl &= ~NCR_SOCL_ATN; - if (insn & (1 << 10)) - dev->carry = 0; - break; - } - } else { - reg = ((insn >> 16) & 0x7f) | (insn & 0x80); - data8 = (insn >> 8) & 0xff; - opcode = (insn >> 27) & 7; - operator = (insn >> 24) & 7; - op0 = op1 = 0; - switch (opcode) { - case 5: /* From SFBR */ - op0 = dev->sfbr; - op1 = data8; - break; - case 6: /* To SFBR */ - if (operator) - op0 = ncr53c8xx_reg_readb(dev, reg); - op1 = data8; - break; - case 7: /* Read-modify-write */ - if (operator) - op0 = ncr53c8xx_reg_readb(dev, reg); - if (insn & (1 << 23)) - op1 = dev->sfbr; - else - op1 = data8; - break; - } + case 1: /* IO or Read/Write instruction. */ + ncr53c8xx_log("01: I/O or Read/Write instruction\n"); + opcode = (insn >> 27) & 7; + if (opcode < 5) { + if (insn & (1 << 25)) + id = read_dword(dev, dev->dsa + sextract32(insn, 0, 24)); + else + id = insn; + id = (id >> 16) & 0xf; + if (insn & (1 << 26)) + addr = dev->dsp + sextract32(addr, 0, 24); + dev->dnad = addr; + switch (opcode) { + case 0: /* Select */ + dev->sdid = id; + if (dev->scntl1 & NCR_SCNTL1_CON) { + ncr53c8xx_log("Already reselected, jumping to alternative address\n"); + dev->dsp = dev->dnad; + break; + } + dev->sstat0 |= NCR_SSTAT0_WOA; + dev->scntl1 &= ~NCR_SCNTL1_IARB; + if (!scsi_device_present(&scsi_devices[dev->bus][id])) { + ncr53c8xx_bad_selection(dev, id); + break; + } + ncr53c8xx_log("Selected target %d%s\n", + id, insn & (1 << 24) ? " ATN" : ""); + dev->scntl1 |= NCR_SCNTL1_CON; + if (insn & (1 << 24)) + dev->socl |= NCR_SOCL_ATN; + ncr53c8xx_set_phase(dev, PHASE_MO); + dev->waiting = 0; + break; + case 1: /* Disconnect */ + ncr53c8xx_log("Wait Disconnect\n"); + dev->scntl1 &= ~NCR_SCNTL1_CON; + break; + case 2: /* Wait Reselect */ + ncr53c8xx_log("Wait Reselect\n"); + if (dev->istat & NCR_ISTAT_SIGP) + dev->dsp = dev->dnad; /* If SIGP is set, this command causes an immediate jump to DNAD. */ + else { + if (!ncr53c8xx_irq_on_rsl(dev)) + dev->waiting = 1; + } + break; + case 3: /* Set */ + ncr53c8xx_log("Set%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", + insn & (1 << 6) ? " ACK" : "", + insn & (1 << 9) ? " TM" : "", + insn & (1 << 10) ? " CC" : ""); + if (insn & (1 << 3)) { + dev->socl |= NCR_SOCL_ATN; + ncr53c8xx_set_phase(dev, PHASE_MO); + } + if (insn & (1 << 9)) + ncr53c8xx_log("Target mode not implemented\n"); + if (insn & (1 << 10)) + dev->carry = 1; + break; + case 4: /* Clear */ + ncr53c8xx_log("Clear%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", + insn & (1 << 6) ? " ACK" : "", + insn & (1 << 9) ? " TM" : "", + insn & (1 << 10) ? " CC" : ""); + if (insn & (1 << 3)) + dev->socl &= ~NCR_SOCL_ATN; + if (insn & (1 << 10)) + dev->carry = 0; + break; + } + } else { + reg = ((insn >> 16) & 0x7f) | (insn & 0x80); + data8 = (insn >> 8) & 0xff; + opcode = (insn >> 27) & 7; + operator=(insn >> 24) & 7; + op0 = op1 = 0; + switch (opcode) { + case 5: /* From SFBR */ + op0 = dev->sfbr; + op1 = data8; + break; + case 6: /* To SFBR */ + if (operator) + op0 = ncr53c8xx_reg_readb(dev, reg); + op1 = data8; + break; + case 7: /* Read-modify-write */ + if (operator) + op0 = ncr53c8xx_reg_readb(dev, reg); + if (insn & (1 << 23)) + op1 = dev->sfbr; + else + op1 = data8; + break; + } - switch (operator) { - case 0: /* move */ - op0 = op1; - break; - case 1: /* Shift left */ - op1 = op0 >> 7; - op0 = (op0 << 1) | dev->carry; - dev->carry = op1; - break; - case 2: /* OR */ - op0 |= op1; - break; - case 3: /* XOR */ - op0 ^= op1; - break; - case 4: /* AND */ - op0 &= op1; - break; - case 5: /* SHR */ - op1 = op0 & 1; - op0 = (op0 >> 1) | (dev->carry << 7); - dev->carry = op1; - break; - case 6: /* ADD */ - op0 += op1; - dev->carry = op0 < op1; - break; - case 7: /* ADC */ - op0 += op1 + dev->carry; - if (dev->carry) - dev->carry = op0 <= op1; - else - dev->carry = op0 < op1; - break; - } + switch (operator) { + case 0: /* move */ + op0 = op1; + break; + case 1: /* Shift left */ + op1 = op0 >> 7; + op0 = (op0 << 1) | dev->carry; + dev->carry = op1; + break; + case 2: /* OR */ + op0 |= op1; + break; + case 3: /* XOR */ + op0 ^= op1; + break; + case 4: /* AND */ + op0 &= op1; + break; + case 5: /* SHR */ + op1 = op0 & 1; + op0 = (op0 >> 1) | (dev->carry << 7); + dev->carry = op1; + break; + case 6: /* ADD */ + op0 += op1; + dev->carry = op0 < op1; + break; + case 7: /* ADC */ + op0 += op1 + dev->carry; + if (dev->carry) + dev->carry = op0 <= op1; + else + dev->carry = op0 < op1; + break; + } - switch (opcode) { - case 5: /* From SFBR */ - case 7: /* Read-modify-write */ - ncr53c8xx_reg_writeb(dev, reg, op0); - break; - case 6: /* To SFBR */ - dev->sfbr = op0; - break; - } - } - break; + switch (opcode) { + case 5: /* From SFBR */ + case 7: /* Read-modify-write */ + ncr53c8xx_reg_writeb(dev, reg, op0); + break; + case 6: /* To SFBR */ + dev->sfbr = op0; + break; + } + } + break; - case 2: /* Transfer Control. */ - ncr53c8xx_log("02: Transfer Control\n"); - if ((insn & 0x002e0000) == 0) { - ncr53c8xx_log("NOP\n"); - break; - } - if (dev->sist1 & NCR_SIST1_STO) { - ncr53c8xx_log("Delayed select timeout\n"); - dev->sstop = 1; - break; - } - cond = jmp = (insn & (1 << 19)) != 0; - if (cond == jmp && (insn & (1 << 21))) { - ncr53c8xx_log("Compare carry %d\n", dev->carry == jmp); - cond = dev->carry != 0; - } - if (cond == jmp && (insn & (1 << 17))) { - ncr53c8xx_log("Compare phase %d %c= %d\n", (dev->sstat1 & PHASE_MASK), - jmp ? '=' : '!', ((insn >> 24) & 7)); - cond = (dev->sstat1 & PHASE_MASK) == ((insn >> 24) & 7); - } - if (cond == jmp && (insn & (1 << 18))) { - mask = (~insn >> 8) & 0xff; - ncr53c8xx_log("Compare data 0x%x & 0x%x %c= 0x%x\n", dev->sfbr, mask, - jmp ? '=' : '!', insn & mask); - cond = (dev->sfbr & mask) == (insn & mask); - } - if (cond == jmp) { - if (insn & (1 << 23)) { - /* Relative address. */ - addr = dev->dsp + sextract32(addr, 0, 24); - } - switch ((insn >> 27) & 7) { - case 0: /* Jump */ - ncr53c8xx_log("Jump to 0x%08x\n", addr); - dev->adder = addr; - dev->dsp = addr; - break; - case 1: /* Call */ - ncr53c8xx_log("Call 0x%08x\n", addr); - dev->temp = dev->dsp; - dev->dsp = addr; - break; - case 2: /* Return */ - ncr53c8xx_log("Return to 0x%08x\n", dev->temp); - dev->dsp = dev->temp; - break; - case 3: /* Interrupt */ - ncr53c8xx_log("Interrupt 0x%08x\n", dev->dsps); - if ((insn & (1 << 20)) != 0) { - dev->istat |= NCR_ISTAT_INTF; - ncr53c8xx_update_irq(dev); - } else - ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SIR); - break; - default: - ncr53c8xx_log("Illegal transfer control\n"); - ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_IID); - break; - } - } else - ncr53c8xx_log("Control condition failed\n"); - break; + case 2: /* Transfer Control. */ + ncr53c8xx_log("02: Transfer Control\n"); + if ((insn & 0x002e0000) == 0) { + ncr53c8xx_log("NOP\n"); + break; + } + if (dev->sist1 & NCR_SIST1_STO) { + ncr53c8xx_log("Delayed select timeout\n"); + dev->sstop = 1; + break; + } + cond = jmp = (insn & (1 << 19)) != 0; + if (cond == jmp && (insn & (1 << 21))) { + ncr53c8xx_log("Compare carry %d\n", dev->carry == jmp); + cond = dev->carry != 0; + } + if (cond == jmp && (insn & (1 << 17))) { + ncr53c8xx_log("Compare phase %d %c= %d\n", (dev->sstat1 & PHASE_MASK), + jmp ? '=' : '!', ((insn >> 24) & 7)); + cond = (dev->sstat1 & PHASE_MASK) == ((insn >> 24) & 7); + } + if (cond == jmp && (insn & (1 << 18))) { + mask = (~insn >> 8) & 0xff; + ncr53c8xx_log("Compare data 0x%x & 0x%x %c= 0x%x\n", dev->sfbr, mask, + jmp ? '=' : '!', insn & mask); + cond = (dev->sfbr & mask) == (insn & mask); + } + if (cond == jmp) { + if (insn & (1 << 23)) { + /* Relative address. */ + addr = dev->dsp + sextract32(addr, 0, 24); + } + switch ((insn >> 27) & 7) { + case 0: /* Jump */ + ncr53c8xx_log("Jump to 0x%08x\n", addr); + dev->adder = addr; + dev->dsp = addr; + break; + case 1: /* Call */ + ncr53c8xx_log("Call 0x%08x\n", addr); + dev->temp = dev->dsp; + dev->dsp = addr; + break; + case 2: /* Return */ + ncr53c8xx_log("Return to 0x%08x\n", dev->temp); + dev->dsp = dev->temp; + break; + case 3: /* Interrupt */ + ncr53c8xx_log("Interrupt 0x%08x\n", dev->dsps); + if ((insn & (1 << 20)) != 0) { + dev->istat |= NCR_ISTAT_INTF; + ncr53c8xx_update_irq(dev); + } else + ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SIR); + break; + default: + ncr53c8xx_log("Illegal transfer control\n"); + ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_IID); + break; + } + } else + ncr53c8xx_log("Control condition failed\n"); + break; - case 3: - ncr53c8xx_log("00: Memory move\n"); - if ((insn & (1 << 29)) == 0) { - /* Memory move. */ - /* ??? The docs imply the destination address is loaded into - the TEMP register. However the Linux drivers rely on - the value being presrved. */ - dest = read_dword(dev, dev->dsp); - dev->dsp += 4; - ncr53c8xx_memcpy(dev, dest, addr, insn & 0xffffff); - } else { + case 3: + ncr53c8xx_log("00: Memory move\n"); + if ((insn & (1 << 29)) == 0) { + /* Memory move. */ + /* ??? The docs imply the destination address is loaded into + the TEMP register. However the Linux drivers rely on + the value being presrved. */ + dest = read_dword(dev, dev->dsp); + dev->dsp += 4; + ncr53c8xx_memcpy(dev, dest, addr, insn & 0xffffff); + } else { #ifdef ENABLE_NCR53C8XX_LOG - pp = data; + pp = data; #endif - if (insn & (1 << 28)) - addr = dev->dsa + sextract32(addr, 0, 24); - n = (insn & 7); - reg = (insn >> 16) & 0xff; - if (insn & (1 << 24)) { - dma_bm_read(addr, data, n, 4); - for (i = 0; i < n; i++) - ncr53c8xx_reg_writeb(dev, reg + i, data[i]); - } else { - ncr53c8xx_log("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr); - for (i = 0; i < n; i++) - data[i] = ncr53c8xx_reg_readb(dev, reg + i); - dma_bm_write(addr, data, n, 4); - } - } - break; + if (insn & (1 << 28)) + addr = dev->dsa + sextract32(addr, 0, 24); + n = (insn & 7); + reg = (insn >> 16) & 0xff; + if (insn & (1 << 24)) { + dma_bm_read(addr, data, n, 4); + for (i = 0; i < n; i++) + ncr53c8xx_reg_writeb(dev, reg + i, data[i]); + } else { + ncr53c8xx_log("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr); + for (i = 0; i < n; i++) + data[i] = ncr53c8xx_reg_readb(dev, reg + i); + dma_bm_write(addr, data, n, 4); + } + } + break; - default: - ncr53c8xx_log("%02X: Unknown command\n", (uint8_t) (insn >> 30)); + default: + ncr53c8xx_log("%02X: Unknown command\n", (uint8_t) (insn >> 30)); } ncr53c8xx_log("instructions processed %i\n", insn_processed); if (insn_processed > 10000 && !dev->waiting) { - /* Some windows drivers make the device spin waiting for a memory - location to change. If we have been executed a lot of code then - assume this is the case and force an unexpected device disconnect. - This is apparently sufficient to beat the drivers into submission. - */ - ncr53c8xx_log("Some windows drivers make the device spin...\n"); - if (!(dev->sien0 & NCR_SIST0_UDC)) - ncr53c8xx_log("inf. loop with UDC masked\n"); - ncr53c8xx_script_scsi_interrupt(dev, NCR_SIST0_UDC, 0); - ncr53c8xx_disconnect(dev); + /* Some windows drivers make the device spin waiting for a memory + location to change. If we have been executed a lot of code then + assume this is the case and force an unexpected device disconnect. + This is apparently sufficient to beat the drivers into submission. + */ + ncr53c8xx_log("Some windows drivers make the device spin...\n"); + if (!(dev->sien0 & NCR_SIST0_UDC)) + ncr53c8xx_log("inf. loop with UDC masked\n"); + ncr53c8xx_script_scsi_interrupt(dev, NCR_SIST0_UDC, 0); + ncr53c8xx_disconnect(dev); } else if (!dev->sstop && !dev->waiting) { - if (dev->dcntl & NCR_DCNTL_SSM) { - ncr53c8xx_log("NCR 810: SCRIPTS: Single-step mode\n"); - ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SSI); - } else { - ncr53c8xx_log("NCR 810: SCRIPTS: Normal mode\n"); - if (insn_processed < 100) - goto again; - } + if (dev->dcntl & NCR_DCNTL_SSM) { + ncr53c8xx_log("NCR 810: SCRIPTS: Single-step mode\n"); + ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SSI); + } else { + ncr53c8xx_log("NCR 810: SCRIPTS: Normal mode\n"); + if (insn_processed < 100) + goto again; + } } else { - if (dev->sstop) - ncr53c8xx_log("NCR 810: SCRIPTS: Stopped\n"); - if (dev->waiting) - ncr53c8xx_log("NCR 810: SCRIPTS: Waiting\n"); + if (dev->sstop) + ncr53c8xx_log("NCR 810: SCRIPTS: Stopped\n"); + if (dev->waiting) + ncr53c8xx_log("NCR 810: SCRIPTS: Waiting\n"); } timer_on_auto(&dev->timer, 40.0); @@ -1428,7 +1395,6 @@ again: ncr53c8xx_log("SCRIPTS execution stopped\n"); } - static void ncr53c8xx_execute_script(ncr53c8xx_t *dev) { @@ -1436,55 +1402,73 @@ ncr53c8xx_execute_script(ncr53c8xx_t *dev) timer_on_auto(&dev->timer, 40.0); } - static void ncr53c8xx_callback(void *p) { ncr53c8xx_t *dev = (ncr53c8xx_t *) p; if (!dev->sstop) { - if (dev->waiting) - timer_on_auto(&dev->timer, 40.0); - else - ncr53c8xx_process_script(dev); + if (dev->waiting) + timer_on_auto(&dev->timer, 40.0); + else + ncr53c8xx_process_script(dev); } if (dev->sstop) - timer_stop(&dev->timer); + timer_stop(&dev->timer); } - static void ncr53c8xx_eeprom(ncr53c8xx_t *dev, uint8_t save) { FILE *f; - f = nvr_fopen(dev->nvr_path, save ? "wb": "rb"); + f = nvr_fopen(dev->nvr_path, save ? "wb" : "rb"); if (f) { - if (save) - fwrite(&dev->nvram, sizeof(dev->nvram), 1, f); - else - (void) !fread(&dev->nvram, sizeof(dev->nvram), 1, f); - fclose(f); + if (save) + fwrite(&dev->nvram, sizeof(dev->nvram), 1, f); + else + (void) !fread(&dev->nvram, sizeof(dev->nvram), 1, f); + fclose(f); } } - static void ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val) { uint8_t tmp = 0; #define CASE_SET_REG24(name, addr) \ - case addr : dev->name &= 0xffffff00; dev->name |= val; break; \ - case addr + 1: dev->name &= 0xffff00ff; dev->name |= val << 8; break; \ - case addr + 2: dev->name &= 0xff00ffff; dev->name |= val << 16; break; + case addr: \ + dev->name &= 0xffffff00; \ + dev->name |= val; \ + break; \ + case addr + 1: \ + dev->name &= 0xffff00ff; \ + dev->name |= val << 8; \ + break; \ + case addr + 2: \ + dev->name &= 0xff00ffff; \ + dev->name |= val << 16; \ + break; #define CASE_SET_REG32(name, addr) \ - case addr : dev->name &= 0xffffff00; dev->name |= val; break; \ - case addr + 1: dev->name &= 0xffff00ff; dev->name |= val << 8; break; \ - case addr + 2: dev->name &= 0xff00ffff; dev->name |= val << 16; break; \ - case addr + 3: dev->name &= 0x00ffffff; dev->name |= val << 24; break; + case addr: \ + dev->name &= 0xffffff00; \ + dev->name |= val; \ + break; \ + case addr + 1: \ + dev->name &= 0xffff00ff; \ + dev->name |= val << 8; \ + break; \ + case addr + 2: \ + dev->name &= 0xff00ffff; \ + dev->name |= val << 16; \ + break; \ + case addr + 3: \ + dev->name &= 0x00ffffff; \ + dev->name |= val << 24; \ + break; #ifdef DEBUG_NCR_REG ncr53c8xx_log("Write reg %02x = %02x\n", offset, val); @@ -1493,493 +1477,507 @@ ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val) dev->regop = 1; switch (offset) { - case 0x00: /* SCNTL0 */ - dev->scntl0 = val; - if (val & NCR_SCNTL0_START) { - /* Looks like this (turn on bit 4 of SSTAT0 to mark arbitration in progress) - is enough to make BIOS v4.x happy. */ - ncr53c8xx_log("NCR 810: Selecting SCSI ID %i\n", dev->sdid); - dev->sstat0 |= 0x10; - } - break; - case 0x01: /* SCNTL1 */ - dev->scntl1 = val & ~NCR_SCNTL1_SST; - if (val & NCR_SCNTL1_IARB) { - ncr53c8xx_log("Arbitration lost\n"); - dev->sstat0 |= 0x08; - dev->waiting = 0; - } - if (val & NCR_SCNTL1_RST) { - if (!(dev->sstat0 & NCR_SSTAT0_RST)) { - dev->sstat0 |= NCR_SSTAT0_RST; - ncr53c8xx_script_scsi_interrupt(dev, NCR_SIST0_RST, 0); - } - } else - dev->sstat0 &= ~NCR_SSTAT0_RST; - break; - case 0x02: /* SCNTL2 */ - val &= ~(NCR_SCNTL2_WSR | NCR_SCNTL2_WSS); - dev->scntl2 = val; - break; - case 0x03: /* SCNTL3 */ - dev->scntl3 = val; - break; - case 0x04: /* SCID */ - dev->scid = val; - break; - case 0x05: /* SXFER */ - dev->sxfer = val; - break; - case 0x06: /* SDID */ - if ((dev->ssid & 0x80) && (val & 0xf) != (dev->ssid & 0xf)) - ncr53c8xx_log("Destination ID does not match SSID\n"); - dev->sdid = val & 0xf; - break; - case 0x07: /* GPREG */ - ncr53c8xx_log("NCR 810: GPREG write %02X\n", val); - dev->gpreg = val; - i2c_gpio_set(dev->i2c, (dev->gpreg & 0x02) || ((dev->gpcntl & 0x82) == 0x02), (dev->gpreg & 0x01) || ((dev->gpcntl & 0x41) == 0x01)); - break; - case 0x08: /* SFBR */ - /* The CPU is not allowed to write to this register. However the - SCRIPTS register move instructions are. */ - dev->sfbr = val; - break; - case 0x09: /* SOCL */ - ncr53c8xx_log("NCR 810: SOCL write %02X\n", val); - dev->socl = val; - break; - case 0x0a: case 0x0b: - /* Openserver writes to these readonly registers on startup */ - return; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - /* Linux writes to these readonly registers on startup. */ - return; - CASE_SET_REG32(dsa, 0x10) - case 0x14: /* ISTAT */ - ncr53c8xx_log("ISTAT write: %02X\n", val); - tmp = dev->istat; - dev->istat = (dev->istat & 0x0f) | (val & 0xf0); - if ((val & NCR_ISTAT_ABRT) && !(val & NCR_ISTAT_SRST)) - ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_ABRT); - if (val & NCR_ISTAT_INTF) { - dev->istat &= ~NCR_ISTAT_INTF; - ncr53c8xx_update_irq(dev); - } + case 0x00: /* SCNTL0 */ + dev->scntl0 = val; + if (val & NCR_SCNTL0_START) { + /* Looks like this (turn on bit 4 of SSTAT0 to mark arbitration in progress) + is enough to make BIOS v4.x happy. */ + ncr53c8xx_log("NCR 810: Selecting SCSI ID %i\n", dev->sdid); + dev->sstat0 |= 0x10; + } + break; + case 0x01: /* SCNTL1 */ + dev->scntl1 = val & ~NCR_SCNTL1_SST; + if (val & NCR_SCNTL1_IARB) { + ncr53c8xx_log("Arbitration lost\n"); + dev->sstat0 |= 0x08; + dev->waiting = 0; + } + if (val & NCR_SCNTL1_RST) { + if (!(dev->sstat0 & NCR_SSTAT0_RST)) { + dev->sstat0 |= NCR_SSTAT0_RST; + ncr53c8xx_script_scsi_interrupt(dev, NCR_SIST0_RST, 0); + } + } else + dev->sstat0 &= ~NCR_SSTAT0_RST; + break; + case 0x02: /* SCNTL2 */ + val &= ~(NCR_SCNTL2_WSR | NCR_SCNTL2_WSS); + dev->scntl2 = val; + break; + case 0x03: /* SCNTL3 */ + dev->scntl3 = val; + break; + case 0x04: /* SCID */ + dev->scid = val; + break; + case 0x05: /* SXFER */ + dev->sxfer = val; + break; + case 0x06: /* SDID */ + if ((dev->ssid & 0x80) && (val & 0xf) != (dev->ssid & 0xf)) + ncr53c8xx_log("Destination ID does not match SSID\n"); + dev->sdid = val & 0xf; + break; + case 0x07: /* GPREG */ + ncr53c8xx_log("NCR 810: GPREG write %02X\n", val); + dev->gpreg = val; + i2c_gpio_set(dev->i2c, (dev->gpreg & 0x02) || ((dev->gpcntl & 0x82) == 0x02), (dev->gpreg & 0x01) || ((dev->gpcntl & 0x41) == 0x01)); + break; + case 0x08: /* SFBR */ + /* The CPU is not allowed to write to this register. However the + SCRIPTS register move instructions are. */ + dev->sfbr = val; + break; + case 0x09: /* SOCL */ + ncr53c8xx_log("NCR 810: SOCL write %02X\n", val); + dev->socl = val; + break; + case 0x0a: + case 0x0b: + /* Openserver writes to these readonly registers on startup */ + return; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + /* Linux writes to these readonly registers on startup. */ + return; + CASE_SET_REG32(dsa, 0x10) + case 0x14: /* ISTAT */ + ncr53c8xx_log("ISTAT write: %02X\n", val); + tmp = dev->istat; + dev->istat = (dev->istat & 0x0f) | (val & 0xf0); + if ((val & NCR_ISTAT_ABRT) && !(val & NCR_ISTAT_SRST)) + ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_ABRT); + if (val & NCR_ISTAT_INTF) { + dev->istat &= ~NCR_ISTAT_INTF; + ncr53c8xx_update_irq(dev); + } - if ((dev->waiting == 1) && (val & NCR_ISTAT_SIGP)) { - ncr53c8xx_log("Woken by SIGP\n"); - dev->waiting = 0; - dev->dsp = dev->dnad; - /* ncr53c8xx_execute_script(dev); */ - } - if ((val & NCR_ISTAT_SRST) && !(tmp & NCR_ISTAT_SRST)) { - ncr53c8xx_soft_reset(dev); - ncr53c8xx_update_irq(dev); - dev->istat = 0; - } - break; - case 0x16: /* MBOX0 */ - dev->mbox0 = val; - break; - case 0x17: /* MBOX1 */ - dev->mbox1 = val; - break; - case 0x18: /* CTEST0 */ - /* nothing to do */ - break; - case 0x19: /* CTEST1 */ - /* nothing to do */ - break; - case 0x1a: /* CTEST2 */ - dev->ctest2 = val & NCR_CTEST2_PCICIE; - break; - case 0x1b: /* CTEST3 */ - dev->ctest3 = val & 0x0f; - break; - CASE_SET_REG32(temp, 0x1c) - case 0x21: /* CTEST4 */ - if (val & 7) - ncr53c8xx_log("Unimplemented CTEST4-FBL 0x%x\n", val); - dev->ctest4 = val; - break; - case 0x22: /* CTEST5 */ - if (val & (NCR_CTEST5_ADCK | NCR_CTEST5_BBCK)) - ncr53c8xx_log("CTEST5 DMA increment not implemented\n"); - dev->ctest5 = val; - break; - CASE_SET_REG24(dbc, 0x24) - CASE_SET_REG32(dnad, 0x28) - case 0x2c: /* DSP[0:7] */ - dev->dsp &= 0xffffff00; - dev->dsp |= val; - break; - case 0x2d: /* DSP[8:15] */ - dev->dsp &= 0xffff00ff; - dev->dsp |= val << 8; - break; - case 0x2e: /* DSP[16:23] */ - dev->dsp &= 0xff00ffff; - dev->dsp |= val << 16; - break; - case 0x2f: /* DSP[24:31] */ - dev->dsp &= 0x00ffffff; - dev->dsp |= val << 24; - if (!(dev->dmode & NCR_DMODE_MAN) && dev->sstop) - ncr53c8xx_execute_script(dev); - break; - CASE_SET_REG32(dsps, 0x30) - CASE_SET_REG32(scratcha, 0x34) - case 0x38: /* DMODE */ - dev->dmode = val; - break; - case 0x39: /* DIEN */ - ncr53c8xx_log("DIEN write: %02X\n", val); - dev->dien = val; - ncr53c8xx_update_irq(dev); - break; - case 0x3a: /* SBR */ - dev->sbr = val; - break; - case 0x3b: /* DCNTL */ - dev->dcntl = val & ~(NCR_DCNTL_PFF | NCR_DCNTL_STD); - if ((val & NCR_DCNTL_STD) && dev->sstop) - ncr53c8xx_execute_script(dev); - break; - case 0x40: /* SIEN0 */ - dev->sien0 = val; - ncr53c8xx_update_irq(dev); - break; - case 0x41: /* SIEN1 */ - dev->sien1 = val; - ncr53c8xx_update_irq(dev); - break; - case 0x47: /* GPCNTL */ - ncr53c8xx_log("GPCNTL write: %02X\n", val); - dev->gpcntl = val; - break; - case 0x48: /* STIME0 */ - dev->stime0 = val; - break; - case 0x49: /* STIME1 */ - if (val & 0xf) { - ncr53c8xx_log("General purpose timer not implemented\n"); - /* ??? Raising the interrupt immediately seems to be sufficient - to keep the FreeBSD driver happy. */ - ncr53c8xx_script_scsi_interrupt(dev, 0, NCR_SIST1_GEN); - } - break; - case 0x4a: /* RESPID0 */ - dev->respid0 = val; - break; - case 0x4b: /* RESPID1 */ - if (dev->wide) - dev->respid1 = val; - break; - case 0x4d: /* STEST1 */ - dev->stest1 = val; - break; - case 0x4e: /* STEST2 */ - if (val & 1) - ncr53c8xx_log("Low level mode not implemented\n"); - dev->stest2 = val; - break; - case 0x4f: /* STEST3 */ - if (val & 0x41) - ncr53c8xx_log("SCSI FIFO test mode not implemented\n"); - dev->stest3 = val; - break; - case 0x54: - case 0x55: - break; - CASE_SET_REG32(scratchb, 0x5c) - CASE_SET_REG32(scratchc, 0x60) - CASE_SET_REG32(scratchd, 0x64) - CASE_SET_REG32(scratche, 0x68) - CASE_SET_REG32(scratchf, 0x6c) - CASE_SET_REG32(scratchg, 0x70) - CASE_SET_REG32(scratchh, 0x74) - CASE_SET_REG32(scratchi, 0x78) - CASE_SET_REG32(scratchj, 0x7c) - default: - ncr53c8xx_log("Unhandled writeb 0x%x = 0x%x\n", offset, val); + if ((dev->waiting == 1) && (val & NCR_ISTAT_SIGP)) { + ncr53c8xx_log("Woken by SIGP\n"); + dev->waiting = 0; + dev->dsp = dev->dnad; + /* ncr53c8xx_execute_script(dev); */ + } + if ((val & NCR_ISTAT_SRST) && !(tmp & NCR_ISTAT_SRST)) { + ncr53c8xx_soft_reset(dev); + ncr53c8xx_update_irq(dev); + dev->istat = 0; + } + break; + case 0x16: /* MBOX0 */ + dev->mbox0 = val; + break; + case 0x17: /* MBOX1 */ + dev->mbox1 = val; + break; + case 0x18: /* CTEST0 */ + /* nothing to do */ + break; + case 0x19: /* CTEST1 */ + /* nothing to do */ + break; + case 0x1a: /* CTEST2 */ + dev->ctest2 = val & NCR_CTEST2_PCICIE; + break; + case 0x1b: /* CTEST3 */ + dev->ctest3 = val & 0x0f; + break; + CASE_SET_REG32(temp, 0x1c) + case 0x21: /* CTEST4 */ + if (val & 7) + ncr53c8xx_log("Unimplemented CTEST4-FBL 0x%x\n", val); + dev->ctest4 = val; + break; + case 0x22: /* CTEST5 */ + if (val & (NCR_CTEST5_ADCK | NCR_CTEST5_BBCK)) + ncr53c8xx_log("CTEST5 DMA increment not implemented\n"); + dev->ctest5 = val; + break; + CASE_SET_REG24(dbc, 0x24) + CASE_SET_REG32(dnad, 0x28) + case 0x2c: /* DSP[0:7] */ + dev->dsp &= 0xffffff00; + dev->dsp |= val; + break; + case 0x2d: /* DSP[8:15] */ + dev->dsp &= 0xffff00ff; + dev->dsp |= val << 8; + break; + case 0x2e: /* DSP[16:23] */ + dev->dsp &= 0xff00ffff; + dev->dsp |= val << 16; + break; + case 0x2f: /* DSP[24:31] */ + dev->dsp &= 0x00ffffff; + dev->dsp |= val << 24; + if (!(dev->dmode & NCR_DMODE_MAN) && dev->sstop) + ncr53c8xx_execute_script(dev); + break; + CASE_SET_REG32(dsps, 0x30) + CASE_SET_REG32(scratcha, 0x34) + case 0x38: /* DMODE */ + dev->dmode = val; + break; + case 0x39: /* DIEN */ + ncr53c8xx_log("DIEN write: %02X\n", val); + dev->dien = val; + ncr53c8xx_update_irq(dev); + break; + case 0x3a: /* SBR */ + dev->sbr = val; + break; + case 0x3b: /* DCNTL */ + dev->dcntl = val & ~(NCR_DCNTL_PFF | NCR_DCNTL_STD); + if ((val & NCR_DCNTL_STD) && dev->sstop) + ncr53c8xx_execute_script(dev); + break; + case 0x40: /* SIEN0 */ + dev->sien0 = val; + ncr53c8xx_update_irq(dev); + break; + case 0x41: /* SIEN1 */ + dev->sien1 = val; + ncr53c8xx_update_irq(dev); + break; + case 0x47: /* GPCNTL */ + ncr53c8xx_log("GPCNTL write: %02X\n", val); + dev->gpcntl = val; + break; + case 0x48: /* STIME0 */ + dev->stime0 = val; + break; + case 0x49: /* STIME1 */ + if (val & 0xf) { + ncr53c8xx_log("General purpose timer not implemented\n"); + /* ??? Raising the interrupt immediately seems to be sufficient + to keep the FreeBSD driver happy. */ + ncr53c8xx_script_scsi_interrupt(dev, 0, NCR_SIST1_GEN); + } + break; + case 0x4a: /* RESPID0 */ + dev->respid0 = val; + break; + case 0x4b: /* RESPID1 */ + if (dev->wide) + dev->respid1 = val; + break; + case 0x4d: /* STEST1 */ + dev->stest1 = val; + break; + case 0x4e: /* STEST2 */ + if (val & 1) + ncr53c8xx_log("Low level mode not implemented\n"); + dev->stest2 = val; + break; + case 0x4f: /* STEST3 */ + if (val & 0x41) + ncr53c8xx_log("SCSI FIFO test mode not implemented\n"); + dev->stest3 = val; + break; + case 0x54: + case 0x55: + break; + CASE_SET_REG32(scratchb, 0x5c) + CASE_SET_REG32(scratchc, 0x60) + CASE_SET_REG32(scratchd, 0x64) + CASE_SET_REG32(scratche, 0x68) + CASE_SET_REG32(scratchf, 0x6c) + CASE_SET_REG32(scratchg, 0x70) + CASE_SET_REG32(scratchh, 0x74) + CASE_SET_REG32(scratchi, 0x78) + CASE_SET_REG32(scratchj, 0x7c) + default: + ncr53c8xx_log("Unhandled writeb 0x%x = 0x%x\n", offset, val); } #undef CASE_SET_REG24 #undef CASE_SET_REG32 } - static uint8_t ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset) { uint8_t tmp; -#define CASE_GET_REG24(name, addr) \ - case addr: return dev->name & 0xff; \ - case addr + 1: return (dev->name >> 8) & 0xff; \ - case addr + 2: return (dev->name >> 16) & 0xff; +#define CASE_GET_REG24(name, addr) \ + case addr: \ + return dev->name & 0xff; \ + case addr + 1: \ + return (dev->name >> 8) & 0xff; \ + case addr + 2: \ + return (dev->name >> 16) & 0xff; -#define CASE_GET_REG32(name, addr) \ - case addr: return dev->name & 0xff; \ - case addr + 1: return (dev->name >> 8) & 0xff; \ - case addr + 2: return (dev->name >> 16) & 0xff; \ - case addr + 3: return (dev->name >> 24) & 0xff; +#define CASE_GET_REG32(name, addr) \ + case addr: \ + return dev->name & 0xff; \ + case addr + 1: \ + return (dev->name >> 8) & 0xff; \ + case addr + 2: \ + return (dev->name >> 16) & 0xff; \ + case addr + 3: \ + return (dev->name >> 24) & 0xff; -#define CASE_GET_REG32_COND(name, addr) \ - case addr: if (dev->wide) \ - return dev->name & 0xff; \ - else \ - return 0x00; \ - case addr + 1: if (dev->wide) \ - return (dev->name >> 8) & 0xff; \ - else \ - return 0x00; \ - case addr + 2: if (dev->wide) \ - return (dev->name >> 16) & 0xff; \ - else \ - return 0x00; \ - case addr + 3: if (dev->wide) \ - return (dev->name >> 24) & 0xff; \ - else \ - return 0x00; +#define CASE_GET_REG32_COND(name, addr) \ + case addr: \ + if (dev->wide) \ + return dev->name & 0xff; \ + else \ + return 0x00; \ + case addr + 1: \ + if (dev->wide) \ + return (dev->name >> 8) & 0xff; \ + else \ + return 0x00; \ + case addr + 2: \ + if (dev->wide) \ + return (dev->name >> 16) & 0xff; \ + else \ + return 0x00; \ + case addr + 3: \ + if (dev->wide) \ + return (dev->name >> 24) & 0xff; \ + else \ + return 0x00; dev->regop = 1; switch (offset) { - case 0x00: /* SCNTL0 */ - ncr53c8xx_log("NCR 810: Read SCNTL0 %02X\n", dev->scntl0); - return dev->scntl0; - case 0x01: /* SCNTL1 */ - ncr53c8xx_log("NCR 810: Read SCNTL1 %02X\n", dev->scntl1); - return dev->scntl1; - case 0x02: /* SCNTL2 */ - ncr53c8xx_log("NCR 810: Read SCNTL2 %02X\n", dev->scntl2); - return dev->scntl2; - case 0x03: /* SCNTL3 */ - ncr53c8xx_log("NCR 810: Read SCNTL3 %02X\n", dev->scntl3); - return dev->scntl3; - case 0x04: /* SCID */ - ncr53c8xx_log("NCR 810: Read SCID %02X\n", dev->scid); - return dev->scid & ~0x40; - case 0x05: /* SXFER */ - ncr53c8xx_log("NCR 810: Read SXFER %02X\n", dev->sxfer); - return dev->sxfer; - case 0x06: /* SDID */ - ncr53c8xx_log("NCR 810: Read SDID %02X\n", dev->sdid); - return dev->sdid; - case 0x07: /* GPREG */ - tmp = (dev->gpreg & (dev->gpcntl ^ 0x1f)) & 0x1f; - if ((dev->gpcntl & 0x41) == 0x01) { - tmp &= 0xfe; - if (i2c_gpio_get_sda(dev->i2c)) - tmp |= 0x01; - } - if ((dev->gpcntl & 0x82) == 0x02) { - tmp &= 0xfd; - if (i2c_gpio_get_scl(dev->i2c)) - tmp |= 0x02; - } + case 0x00: /* SCNTL0 */ + ncr53c8xx_log("NCR 810: Read SCNTL0 %02X\n", dev->scntl0); + return dev->scntl0; + case 0x01: /* SCNTL1 */ + ncr53c8xx_log("NCR 810: Read SCNTL1 %02X\n", dev->scntl1); + return dev->scntl1; + case 0x02: /* SCNTL2 */ + ncr53c8xx_log("NCR 810: Read SCNTL2 %02X\n", dev->scntl2); + return dev->scntl2; + case 0x03: /* SCNTL3 */ + ncr53c8xx_log("NCR 810: Read SCNTL3 %02X\n", dev->scntl3); + return dev->scntl3; + case 0x04: /* SCID */ + ncr53c8xx_log("NCR 810: Read SCID %02X\n", dev->scid); + return dev->scid & ~0x40; + case 0x05: /* SXFER */ + ncr53c8xx_log("NCR 810: Read SXFER %02X\n", dev->sxfer); + return dev->sxfer; + case 0x06: /* SDID */ + ncr53c8xx_log("NCR 810: Read SDID %02X\n", dev->sdid); + return dev->sdid; + case 0x07: /* GPREG */ + tmp = (dev->gpreg & (dev->gpcntl ^ 0x1f)) & 0x1f; + if ((dev->gpcntl & 0x41) == 0x01) { + tmp &= 0xfe; + if (i2c_gpio_get_sda(dev->i2c)) + tmp |= 0x01; + } + if ((dev->gpcntl & 0x82) == 0x02) { + tmp &= 0xfd; + if (i2c_gpio_get_scl(dev->i2c)) + tmp |= 0x02; + } - ncr53c8xx_log("NCR 810: Read GPREG %02X\n", tmp); - return tmp; - case 0x08: /* Revision ID */ - ncr53c8xx_log("NCR 810: Read REVID 00\n"); - return 0x00; - case 0xa: /* SSID */ - ncr53c8xx_log("NCR 810: Read SSID %02X\n", dev->ssid); - return dev->ssid; - case 0xb: /* SBCL */ - /* Bit 7 = REQ (SREQ/ status) - Bit 6 = ACK (SACK/ status) - Bit 5 = BSY (SBSY/ status) - Bit 4 = SEL (SSEL/ status) - Bit 3 = ATN (SATN/ status) - Bit 2 = MSG (SMSG/ status) - Bit 1 = C/D (SC_D/ status) - Bit 0 = I/O (SI_O/ status) */ - tmp = (dev->sstat1 & 7); - ncr53c8xx_log("NCR 810: Read SBCL %02X\n", tmp); - return tmp; /* For now, return the MSG, C/D, and I/O bits from SSTAT1. */ - case 0xc: /* DSTAT */ - tmp = dev->dstat | NCR_DSTAT_DFE; - if ((dev->istat & NCR_ISTAT_INTF) == 0) - dev->dstat = 0; - ncr53c8xx_update_irq(dev); - ncr53c8xx_log("NCR 810: Read DSTAT %02X\n", tmp); - return tmp; - case 0x0d: /* SSTAT0 */ - ncr53c8xx_log("NCR 810: Read SSTAT0 %02X\n", dev->sstat0); - return dev->sstat0; - case 0x0e: /* SSTAT1 */ - ncr53c8xx_log("NCR 810: Read SSTAT1 %02X\n", dev->sstat1); - return dev->sstat1; - case 0x0f: /* SSTAT2 */ - ncr53c8xx_log("NCR 810: Read SSTAT2 %02X\n", dev->scntl1 & NCR_SCNTL1_CON ? 0 : 2); - return dev->scntl1 & NCR_SCNTL1_CON ? 0 : 2; - CASE_GET_REG32(dsa, 0x10) - case 0x14: /* ISTAT */ - ncr53c8xx_log("NCR 810: Read ISTAT %02X\n", dev->istat); - tmp = dev->istat; - return tmp; - case 0x16: /* MBOX0 */ - if (dev->wide) - return 0x00; - ncr53c8xx_log("NCR 810: Read MBOX0 %02X\n", dev->mbox0); - return dev->mbox0; - case 0x17: /* MBOX1 */ - if (dev->wide) - return 0x00; - ncr53c8xx_log("NCR 810: Read MBOX1 %02X\n", dev->mbox1); - return dev->mbox1; - case 0x18: /* CTEST0 */ - ncr53c8xx_log("NCR 810: Read CTEST0 FF\n"); - return 0xff; - case 0x19: /* CTEST1 */ - ncr53c8xx_log("NCR 810: Read CTEST1 F0\n"); - return 0xf0; /* dma fifo empty */ - case 0x1a: /* CTEST2 */ - tmp = dev->ctest2 | NCR_CTEST2_DACK | NCR_CTEST2_CM; - if (dev->istat & NCR_ISTAT_SIGP) { - dev->istat &= ~NCR_ISTAT_SIGP; - tmp |= NCR_CTEST2_SIGP; - } - ncr53c8xx_log("NCR 810: Read CTEST2 %02X\n", tmp); - return tmp; - case 0x1b: /* CTEST3 */ - ncr53c8xx_log("NCR 810: Read CTEST3 %02X\n", - (dev->ctest3 & (0x08 | 0x02 | 0x01)) | ((dev->chip_rev & 0x0f) << 4)); - return (dev->ctest3 & (0x08 | 0x02 | 0x01)) | ((dev->chip_rev & 0x0f) << 4); - CASE_GET_REG32(temp, 0x1c) - case 0x20: /* DFIFO */ - ncr53c8xx_log("NCR 810: Read DFIFO 00\n"); - return 0; - case 0x21: /* CTEST4 */ - ncr53c8xx_log("NCR 810: Read CTEST4 %02X\n", dev->ctest4); - return dev->ctest4; - case 0x22: /* CTEST5 */ - ncr53c8xx_log("NCR 810: Read CTEST5 %02X\n", dev->ctest5); - return dev->ctest5; - case 0x23: /* CTEST6 */ - ncr53c8xx_log("NCR 810: Read CTEST6 00\n"); - return 0; - CASE_GET_REG24(dbc, 0x24) - case 0x27: /* DCMD */ - ncr53c8xx_log("NCR 810: Read DCMD %02X\n", dev->dcmd); - return dev->dcmd; - CASE_GET_REG32(dnad, 0x28) - CASE_GET_REG32(dsp, 0x2c) - CASE_GET_REG32(dsps, 0x30) - CASE_GET_REG32(scratcha, 0x34) - case 0x38: /* DMODE */ - ncr53c8xx_log("NCR 810: Read DMODE %02X\n", dev->dmode); - return dev->dmode; - case 0x39: /* DIEN */ - ncr53c8xx_log("NCR 810: Read DIEN %02X\n", dev->dien); - return dev->dien; - case 0x3a: /* SBR */ - ncr53c8xx_log("NCR 810: Read SBR %02X\n", dev->sbr); - return dev->sbr; - case 0x3b: /* DCNTL */ - ncr53c8xx_log("NCR 810: Read DCNTL %02X\n", dev->dcntl); - return dev->dcntl; - CASE_GET_REG32(adder, 0x3c) /* ADDER Output (Debug of relative jump address) */ - case 0x40: /* SIEN0 */ - ncr53c8xx_log("NCR 810: Read SIEN0 %02X\n", dev->sien0); - return dev->sien0; - case 0x41: /* SIEN1 */ - ncr53c8xx_log("NCR 810: Read SIEN1 %02X\n", dev->sien1); - return dev->sien1; - case 0x42: /* SIST0 */ - tmp = dev->sist0; - dev->sist0 = 0x00; - ncr53c8xx_update_irq(dev); - ncr53c8xx_log("NCR 810: Read SIST0 %02X\n", tmp); - return tmp; - case 0x43: /* SIST1 */ - tmp = dev->sist1; - dev->sist1 = 0x00; - ncr53c8xx_update_irq(dev); - ncr53c8xx_log("NCR 810: Read SIST1 %02X\n", tmp); - return tmp; - case 0x44: /* SLPAR */ - if (!dev->wide) - return 0x00; - ncr53c8xx_log("NCR 810: Read SLPAR %02X\n", dev->stime0); - return dev->slpar; - case 0x45: /* SWIDE */ - if (!dev->wide) - return 0x00; - ncr53c8xx_log("NCR 810: Read SWIDE %02X\n", dev->stime0); - return dev->swide; - case 0x46: /* MACNTL */ - ncr53c8xx_log("NCR 810: Read MACNTL 4F\n"); - return 0x4f; - case 0x47: /* GPCNTL */ - ncr53c8xx_log("NCR 810: Read GPCNTL %02X\n", dev->gpcntl); - return dev->gpcntl; - case 0x48: /* STIME0 */ - ncr53c8xx_log("NCR 810: Read STIME0 %02X\n", dev->stime0); - return dev->stime0; - case 0x4a: /* RESPID0 */ - if (dev->wide) { - ncr53c8xx_log("NCR 810: Read RESPID0 %02X\n", dev->respid0); - } else { - ncr53c8xx_log("NCR 810: Read RESPID %02X\n", dev->respid0); - } - return dev->respid0; - case 0x4b: /* RESPID1 */ - if (!dev->wide) - return 0x00; - ncr53c8xx_log("NCR 810: Read RESPID1 %02X\n", dev->respid1); - return dev->respid1; - case 0x4c: /* STEST0 */ - ncr53c8xx_log("NCR 810: Read STEST0 %02X\n", dev->stest1); - return 0x00; - case 0x4d: /* STEST1 */ - ncr53c8xx_log("NCR 810: Read STEST1 %02X\n", dev->stest1); - return dev->stest1; - case 0x4e: /* STEST2 */ - ncr53c8xx_log("NCR 810: Read STEST2 %02X\n", dev->stest2); - return dev->stest2; - case 0x4f: /* STEST3 */ - ncr53c8xx_log("NCR 810: Read STEST3 %02X\n", dev->stest3); - return dev->stest3; - case 0x50: /* SIDL0 */ - /* This is needed by the linux drivers. We currently only update it - during the MSG IN phase. */ - if (dev->wide) { - ncr53c8xx_log("NCR 810: Read SIDL0 %02X\n", dev->sidl0); - } else { - ncr53c8xx_log("NCR 810: Read SIDL %02X\n", dev->sidl0); - } - return dev->sidl0; - case 0x51: /* SIDL1 */ - if (!dev->wide) - return 0x00; - ncr53c8xx_log("NCR 810: Read SIDL1 %02X\n", dev->sidl1); - return dev->sidl1; - case 0x52: /* STEST4 */ - ncr53c8xx_log("NCR 810: Read STEST4 E0\n"); - return 0xe0; - case 0x58: /* SBDL */ - /* Some drivers peek at the data bus during the MSG IN phase. */ - if ((dev->sstat1 & PHASE_MASK) == PHASE_MI) { - ncr53c8xx_log("NCR 810: Read SBDL %02X\n", dev->msg[0]); - return dev->msg[0]; - } - ncr53c8xx_log("NCR 810: Read SBDL 00\n"); - return 0; - case 0x59: /* SBDL high */ - ncr53c8xx_log("NCR 810: Read SBDLH 00\n"); - return 0; - CASE_GET_REG32(scratchb, 0x5c) - CASE_GET_REG32_COND(scratchc, 0x60) - CASE_GET_REG32_COND(scratchd, 0x64) - CASE_GET_REG32_COND(scratche, 0x68) - CASE_GET_REG32_COND(scratchf, 0x6c) - CASE_GET_REG32_COND(scratchg, 0x70) - CASE_GET_REG32_COND(scratchh, 0x74) - CASE_GET_REG32_COND(scratchi, 0x78) - CASE_GET_REG32_COND(scratchj, 0x7c) + ncr53c8xx_log("NCR 810: Read GPREG %02X\n", tmp); + return tmp; + case 0x08: /* Revision ID */ + ncr53c8xx_log("NCR 810: Read REVID 00\n"); + return 0x00; + case 0xa: /* SSID */ + ncr53c8xx_log("NCR 810: Read SSID %02X\n", dev->ssid); + return dev->ssid; + case 0xb: /* SBCL */ + /* Bit 7 = REQ (SREQ/ status) + Bit 6 = ACK (SACK/ status) + Bit 5 = BSY (SBSY/ status) + Bit 4 = SEL (SSEL/ status) + Bit 3 = ATN (SATN/ status) + Bit 2 = MSG (SMSG/ status) + Bit 1 = C/D (SC_D/ status) + Bit 0 = I/O (SI_O/ status) */ + tmp = (dev->sstat1 & 7); + ncr53c8xx_log("NCR 810: Read SBCL %02X\n", tmp); + return tmp; /* For now, return the MSG, C/D, and I/O bits from SSTAT1. */ + case 0xc: /* DSTAT */ + tmp = dev->dstat | NCR_DSTAT_DFE; + if ((dev->istat & NCR_ISTAT_INTF) == 0) + dev->dstat = 0; + ncr53c8xx_update_irq(dev); + ncr53c8xx_log("NCR 810: Read DSTAT %02X\n", tmp); + return tmp; + case 0x0d: /* SSTAT0 */ + ncr53c8xx_log("NCR 810: Read SSTAT0 %02X\n", dev->sstat0); + return dev->sstat0; + case 0x0e: /* SSTAT1 */ + ncr53c8xx_log("NCR 810: Read SSTAT1 %02X\n", dev->sstat1); + return dev->sstat1; + case 0x0f: /* SSTAT2 */ + ncr53c8xx_log("NCR 810: Read SSTAT2 %02X\n", dev->scntl1 & NCR_SCNTL1_CON ? 0 : 2); + return dev->scntl1 & NCR_SCNTL1_CON ? 0 : 2; + CASE_GET_REG32(dsa, 0x10) + case 0x14: /* ISTAT */ + ncr53c8xx_log("NCR 810: Read ISTAT %02X\n", dev->istat); + tmp = dev->istat; + return tmp; + case 0x16: /* MBOX0 */ + if (dev->wide) + return 0x00; + ncr53c8xx_log("NCR 810: Read MBOX0 %02X\n", dev->mbox0); + return dev->mbox0; + case 0x17: /* MBOX1 */ + if (dev->wide) + return 0x00; + ncr53c8xx_log("NCR 810: Read MBOX1 %02X\n", dev->mbox1); + return dev->mbox1; + case 0x18: /* CTEST0 */ + ncr53c8xx_log("NCR 810: Read CTEST0 FF\n"); + return 0xff; + case 0x19: /* CTEST1 */ + ncr53c8xx_log("NCR 810: Read CTEST1 F0\n"); + return 0xf0; /* dma fifo empty */ + case 0x1a: /* CTEST2 */ + tmp = dev->ctest2 | NCR_CTEST2_DACK | NCR_CTEST2_CM; + if (dev->istat & NCR_ISTAT_SIGP) { + dev->istat &= ~NCR_ISTAT_SIGP; + tmp |= NCR_CTEST2_SIGP; + } + ncr53c8xx_log("NCR 810: Read CTEST2 %02X\n", tmp); + return tmp; + case 0x1b: /* CTEST3 */ + ncr53c8xx_log("NCR 810: Read CTEST3 %02X\n", + (dev->ctest3 & (0x08 | 0x02 | 0x01)) | ((dev->chip_rev & 0x0f) << 4)); + return (dev->ctest3 & (0x08 | 0x02 | 0x01)) | ((dev->chip_rev & 0x0f) << 4); + CASE_GET_REG32(temp, 0x1c) + case 0x20: /* DFIFO */ + ncr53c8xx_log("NCR 810: Read DFIFO 00\n"); + return 0; + case 0x21: /* CTEST4 */ + ncr53c8xx_log("NCR 810: Read CTEST4 %02X\n", dev->ctest4); + return dev->ctest4; + case 0x22: /* CTEST5 */ + ncr53c8xx_log("NCR 810: Read CTEST5 %02X\n", dev->ctest5); + return dev->ctest5; + case 0x23: /* CTEST6 */ + ncr53c8xx_log("NCR 810: Read CTEST6 00\n"); + return 0; + CASE_GET_REG24(dbc, 0x24) + case 0x27: /* DCMD */ + ncr53c8xx_log("NCR 810: Read DCMD %02X\n", dev->dcmd); + return dev->dcmd; + CASE_GET_REG32(dnad, 0x28) + CASE_GET_REG32(dsp, 0x2c) + CASE_GET_REG32(dsps, 0x30) + CASE_GET_REG32(scratcha, 0x34) + case 0x38: /* DMODE */ + ncr53c8xx_log("NCR 810: Read DMODE %02X\n", dev->dmode); + return dev->dmode; + case 0x39: /* DIEN */ + ncr53c8xx_log("NCR 810: Read DIEN %02X\n", dev->dien); + return dev->dien; + case 0x3a: /* SBR */ + ncr53c8xx_log("NCR 810: Read SBR %02X\n", dev->sbr); + return dev->sbr; + case 0x3b: /* DCNTL */ + ncr53c8xx_log("NCR 810: Read DCNTL %02X\n", dev->dcntl); + return dev->dcntl; + CASE_GET_REG32(adder, 0x3c) /* ADDER Output (Debug of relative jump address) */ + case 0x40: /* SIEN0 */ + ncr53c8xx_log("NCR 810: Read SIEN0 %02X\n", dev->sien0); + return dev->sien0; + case 0x41: /* SIEN1 */ + ncr53c8xx_log("NCR 810: Read SIEN1 %02X\n", dev->sien1); + return dev->sien1; + case 0x42: /* SIST0 */ + tmp = dev->sist0; + dev->sist0 = 0x00; + ncr53c8xx_update_irq(dev); + ncr53c8xx_log("NCR 810: Read SIST0 %02X\n", tmp); + return tmp; + case 0x43: /* SIST1 */ + tmp = dev->sist1; + dev->sist1 = 0x00; + ncr53c8xx_update_irq(dev); + ncr53c8xx_log("NCR 810: Read SIST1 %02X\n", tmp); + return tmp; + case 0x44: /* SLPAR */ + if (!dev->wide) + return 0x00; + ncr53c8xx_log("NCR 810: Read SLPAR %02X\n", dev->stime0); + return dev->slpar; + case 0x45: /* SWIDE */ + if (!dev->wide) + return 0x00; + ncr53c8xx_log("NCR 810: Read SWIDE %02X\n", dev->stime0); + return dev->swide; + case 0x46: /* MACNTL */ + ncr53c8xx_log("NCR 810: Read MACNTL 4F\n"); + return 0x4f; + case 0x47: /* GPCNTL */ + ncr53c8xx_log("NCR 810: Read GPCNTL %02X\n", dev->gpcntl); + return dev->gpcntl; + case 0x48: /* STIME0 */ + ncr53c8xx_log("NCR 810: Read STIME0 %02X\n", dev->stime0); + return dev->stime0; + case 0x4a: /* RESPID0 */ + if (dev->wide) { + ncr53c8xx_log("NCR 810: Read RESPID0 %02X\n", dev->respid0); + } else { + ncr53c8xx_log("NCR 810: Read RESPID %02X\n", dev->respid0); + } + return dev->respid0; + case 0x4b: /* RESPID1 */ + if (!dev->wide) + return 0x00; + ncr53c8xx_log("NCR 810: Read RESPID1 %02X\n", dev->respid1); + return dev->respid1; + case 0x4c: /* STEST0 */ + ncr53c8xx_log("NCR 810: Read STEST0 %02X\n", dev->stest1); + return 0x00; + case 0x4d: /* STEST1 */ + ncr53c8xx_log("NCR 810: Read STEST1 %02X\n", dev->stest1); + return dev->stest1; + case 0x4e: /* STEST2 */ + ncr53c8xx_log("NCR 810: Read STEST2 %02X\n", dev->stest2); + return dev->stest2; + case 0x4f: /* STEST3 */ + ncr53c8xx_log("NCR 810: Read STEST3 %02X\n", dev->stest3); + return dev->stest3; + case 0x50: /* SIDL0 */ + /* This is needed by the linux drivers. We currently only update it + during the MSG IN phase. */ + if (dev->wide) { + ncr53c8xx_log("NCR 810: Read SIDL0 %02X\n", dev->sidl0); + } else { + ncr53c8xx_log("NCR 810: Read SIDL %02X\n", dev->sidl0); + } + return dev->sidl0; + case 0x51: /* SIDL1 */ + if (!dev->wide) + return 0x00; + ncr53c8xx_log("NCR 810: Read SIDL1 %02X\n", dev->sidl1); + return dev->sidl1; + case 0x52: /* STEST4 */ + ncr53c8xx_log("NCR 810: Read STEST4 E0\n"); + return 0xe0; + case 0x58: /* SBDL */ + /* Some drivers peek at the data bus during the MSG IN phase. */ + if ((dev->sstat1 & PHASE_MASK) == PHASE_MI) { + ncr53c8xx_log("NCR 810: Read SBDL %02X\n", dev->msg[0]); + return dev->msg[0]; + } + ncr53c8xx_log("NCR 810: Read SBDL 00\n"); + return 0; + case 0x59: /* SBDL high */ + ncr53c8xx_log("NCR 810: Read SBDLH 00\n"); + return 0; + CASE_GET_REG32(scratchb, 0x5c) + CASE_GET_REG32_COND(scratchc, 0x60) + CASE_GET_REG32_COND(scratchd, 0x64) + CASE_GET_REG32_COND(scratche, 0x68) + CASE_GET_REG32_COND(scratchf, 0x6c) + CASE_GET_REG32_COND(scratchg, 0x70) + CASE_GET_REG32_COND(scratchh, 0x74) + CASE_GET_REG32_COND(scratchi, 0x78) + CASE_GET_REG32_COND(scratchj, 0x7c) } ncr53c8xx_log("readb 0x%x\n", offset); return 0; @@ -1988,20 +1986,18 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset) #undef CASE_GET_REG32 } - static uint8_t ncr53c8xx_io_readb(uint16_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; return ncr53c8xx_reg_readb(dev, addr & 0xff); } - static uint16_t ncr53c8xx_io_readw(uint16_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - uint16_t val; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + uint16_t val; addr &= 0xff; val = ncr53c8xx_reg_readb(dev, addr); @@ -2009,12 +2005,11 @@ ncr53c8xx_io_readw(uint16_t addr, void *p) return val; } - static uint32_t ncr53c8xx_io_readl(uint16_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - uint32_t val; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + uint32_t val; addr &= 0xff; val = ncr53c8xx_reg_readb(dev, addr); @@ -2024,29 +2019,26 @@ ncr53c8xx_io_readl(uint16_t addr, void *p) return val; } - static void ncr53c8xx_io_writeb(uint16_t addr, uint8_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - ncr53c8xx_reg_writeb(dev, addr & 0xff, val); + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_reg_writeb(dev, addr & 0xff, val); } - static void ncr53c8xx_io_writew(uint16_t addr, uint16_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - addr &= 0xff; - ncr53c8xx_reg_writeb(dev, addr, val & 0xff); - ncr53c8xx_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + addr &= 0xff; + ncr53c8xx_reg_writeb(dev, addr, val & 0xff); + ncr53c8xx_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); } - static void ncr53c8xx_io_writel(uint16_t addr, uint32_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); ncr53c8xx_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); @@ -2054,31 +2046,28 @@ ncr53c8xx_io_writel(uint16_t addr, uint32_t val, void *p) ncr53c8xx_reg_writeb(dev, addr + 3, (val >> 24) & 0xff); } - static void ncr53c8xx_mmio_writeb(uint32_t addr, uint8_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; ncr53c8xx_reg_writeb(dev, addr & 0xff, val); } - static void ncr53c8xx_mmio_writew(uint32_t addr, uint16_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); ncr53c8xx_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); } - static void ncr53c8xx_mmio_writel(uint32_t addr, uint32_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); @@ -2087,21 +2076,19 @@ ncr53c8xx_mmio_writel(uint32_t addr, uint32_t val, void *p) ncr53c8xx_reg_writeb(dev, addr + 3, (val >> 24) & 0xff); } - static uint8_t ncr53c8xx_mmio_readb(uint32_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; return ncr53c8xx_reg_readb(dev, addr & 0xff); } - static uint16_t ncr53c8xx_mmio_readw(uint32_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - uint16_t val; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + uint16_t val; addr &= 0xff; val = ncr53c8xx_reg_readb(dev, addr); @@ -2109,12 +2096,11 @@ ncr53c8xx_mmio_readw(uint32_t addr, void *p) return val; } - static uint32_t ncr53c8xx_mmio_readl(uint32_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - uint32_t val; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + uint32_t val; addr &= 0xff; val = ncr53c8xx_reg_readb(dev, addr); @@ -2125,16 +2111,14 @@ ncr53c8xx_mmio_readl(uint32_t addr, void *p) return val; } - static void ncr53c8xx_ram_writeb(uint32_t addr, uint8_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; dev->ram[addr & 0x0fff] = val; } - static void ncr53c8xx_ram_writew(uint32_t addr, uint16_t val, void *p) { @@ -2142,7 +2126,6 @@ ncr53c8xx_ram_writew(uint32_t addr, uint16_t val, void *p) ncr53c8xx_ram_writeb(addr + 1, (val >> 8) & 0xff, p); } - static void ncr53c8xx_ram_writel(uint32_t addr, uint32_t val, void *p) { @@ -2152,16 +2135,14 @@ ncr53c8xx_ram_writel(uint32_t addr, uint32_t val, void *p) ncr53c8xx_ram_writeb(addr + 3, (val >> 24) & 0xff, p); } - static uint8_t ncr53c8xx_ram_readb(uint32_t addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; return dev->ram[addr & 0x0fff]; } - static uint16_t ncr53c8xx_ram_readw(uint32_t addr, void *p) { @@ -2173,7 +2154,6 @@ ncr53c8xx_ram_readw(uint32_t addr, void *p) return val; } - static uint32_t ncr53c8xx_ram_readl(uint32_t addr, void *p) { @@ -2187,326 +2167,321 @@ ncr53c8xx_ram_readl(uint32_t addr, void *p) return val; } - static void ncr53c8xx_io_set(ncr53c8xx_t *dev, uint32_t base, uint16_t len) { ncr53c8xx_log("NCR53c8xx: [PCI] Setting I/O handler at %04X\n", base); io_sethandler(base, len, - ncr53c8xx_io_readb, ncr53c8xx_io_readw, ncr53c8xx_io_readl, - ncr53c8xx_io_writeb, ncr53c8xx_io_writew, ncr53c8xx_io_writel, dev); + ncr53c8xx_io_readb, ncr53c8xx_io_readw, ncr53c8xx_io_readl, + ncr53c8xx_io_writeb, ncr53c8xx_io_writew, ncr53c8xx_io_writel, dev); } - static void ncr53c8xx_io_remove(ncr53c8xx_t *dev, uint32_t base, uint16_t len) { ncr53c8xx_log("NCR53c8xx: Removing I/O handler at %04X\n", base); io_removehandler(base, len, - ncr53c8xx_io_readb, ncr53c8xx_io_readw, ncr53c8xx_io_readl, + ncr53c8xx_io_readb, ncr53c8xx_io_readw, ncr53c8xx_io_readl, ncr53c8xx_io_writeb, ncr53c8xx_io_writew, ncr53c8xx_io_writel, dev); } - static void ncr53c8xx_mem_init(ncr53c8xx_t *dev, uint32_t addr) { mem_mapping_add(&dev->mmio_mapping, addr, 0x100, - ncr53c8xx_mmio_readb, ncr53c8xx_mmio_readw, ncr53c8xx_mmio_readl, - ncr53c8xx_mmio_writeb, ncr53c8xx_mmio_writew, ncr53c8xx_mmio_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); + ncr53c8xx_mmio_readb, ncr53c8xx_mmio_readw, ncr53c8xx_mmio_readl, + ncr53c8xx_mmio_writeb, ncr53c8xx_mmio_writew, ncr53c8xx_mmio_writel, + NULL, MEM_MAPPING_EXTERNAL, dev); } - static void ncr53c8xx_ram_init(ncr53c8xx_t *dev, uint32_t addr) { mem_mapping_add(&dev->ram_mapping, addr, 0x1000, - ncr53c8xx_ram_readb, ncr53c8xx_ram_readw, ncr53c8xx_ram_readl, - ncr53c8xx_ram_writeb, ncr53c8xx_ram_writew, ncr53c8xx_ram_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); + ncr53c8xx_ram_readb, ncr53c8xx_ram_readw, ncr53c8xx_ram_readl, + ncr53c8xx_ram_writeb, ncr53c8xx_ram_writew, ncr53c8xx_ram_writel, + NULL, MEM_MAPPING_EXTERNAL, dev); } - static void ncr53c8xx_mem_set_addr(ncr53c8xx_t *dev, uint32_t base) { mem_mapping_set_addr(&dev->mmio_mapping, base, 0x100); } - static void ncr53c8xx_ram_set_addr(ncr53c8xx_t *dev, uint32_t base) { mem_mapping_set_addr(&dev->ram_mapping, base, 0x1000); } - static void ncr53c8xx_bios_set_addr(ncr53c8xx_t *dev, uint32_t base) { if (dev->has_bios == 2) - mem_mapping_set_addr(&dev->bios.mapping, base, 0x10000); + mem_mapping_set_addr(&dev->bios.mapping, base, 0x10000); else if (dev->has_bios == 1) - mem_mapping_set_addr(&dev->bios.mapping, base, 0x04000); + mem_mapping_set_addr(&dev->bios.mapping, base, 0x04000); } - static void ncr53c8xx_mem_disable(ncr53c8xx_t *dev) { mem_mapping_disable(&dev->mmio_mapping); } - static void ncr53c8xx_ram_disable(ncr53c8xx_t *dev) { mem_mapping_disable(&dev->ram_mapping); } - static void ncr53c8xx_bios_disable(ncr53c8xx_t *dev) { mem_mapping_disable(&dev->bios.mapping); } - -uint8_t ncr53c8xx_pci_regs[256]; -bar_t ncr53c8xx_pci_bar[4]; - +uint8_t ncr53c8xx_pci_regs[256]; +bar_t ncr53c8xx_pci_bar[4]; static uint8_t ncr53c8xx_pci_read(int func, int addr, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; ncr53c8xx_log("NCR53c8xx: Reading register %02X\n", addr & 0xff); if ((addr >= 0x80) && (addr <= 0xFF)) - return ncr53c8xx_reg_readb(dev, addr & 0x7F); + return ncr53c8xx_reg_readb(dev, addr & 0x7F); switch (addr) { - case 0x00: - return 0x00; - case 0x01: - return 0x10; - case 0x02: - return dev->chip; - case 0x03: - return 0x00; - case 0x04: - return ncr53c8xx_pci_regs[0x04] & 0x57; /*Respond to IO and memory accesses*/ - case 0x05: - return ncr53c8xx_pci_regs[0x05] & 0x01; - case 0x07: - return 2; - case 0x08: - return dev->chip_rev; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - case 0x0A: - return 0; /*devubclass*/ - case 0x0B: - return 1; /*Class code*/ - case 0x0C: - case 0x0D: - return ncr53c8xx_pci_regs[addr]; - case 0x0E: - return 0; /*Header type */ - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return ncr53c8xx_pci_bar[0].addr_regs[1]; - case 0x12: - return ncr53c8xx_pci_bar[0].addr_regs[2]; - case 0x13: - return ncr53c8xx_pci_bar[0].addr_regs[3]; - case 0x14: - return 0; /*Memory space*/ - case 0x15: - return ncr53c8xx_pci_bar[1].addr_regs[1]; - case 0x16: - return ncr53c8xx_pci_bar[1].addr_regs[2]; - case 0x17: - return ncr53c8xx_pci_bar[1].addr_regs[3]; - case 0x18: - return 0; /*Memory space*/ - case 0x19: - if (!dev->wide) - return 0; - return ncr53c8xx_pci_bar[2].addr_regs[1]; - case 0x1A: - if (!dev->wide) - return 0; - return ncr53c8xx_pci_bar[2].addr_regs[2]; - case 0x1B: - if (!dev->wide) - return 0; - return ncr53c8xx_pci_bar[2].addr_regs[3]; - case 0x2C: - return 0x00; - case 0x2D: - if (dev->wide) - return 0; - return 0x10; - case 0x2E: - if (dev->wide) - return 0; - return 0x01; - case 0x2F: - return 0x00; - case 0x30: - return ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01; - case 0x31: - return ncr53c8xx_pci_bar[3].addr_regs[1]; - case 0x32: - return ncr53c8xx_pci_bar[3].addr_regs[2]; - case 0x33: - return ncr53c8xx_pci_bar[3].addr_regs[3]; - case 0x3C: - return dev->irq; - case 0x3D: - return PCI_INTA; - case 0x3E: - return 0x11; - case 0x3F: - return 0x40; + case 0x00: + return 0x00; + case 0x01: + return 0x10; + case 0x02: + return dev->chip; + case 0x03: + return 0x00; + case 0x04: + return ncr53c8xx_pci_regs[0x04] & 0x57; /*Respond to IO and memory accesses*/ + case 0x05: + return ncr53c8xx_pci_regs[0x05] & 0x01; + case 0x07: + return 2; + case 0x08: + return dev->chip_rev; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0A: + return 0; /*devubclass*/ + case 0x0B: + return 1; /*Class code*/ + case 0x0C: + case 0x0D: + return ncr53c8xx_pci_regs[addr]; + case 0x0E: + return 0; /*Header type */ + case 0x10: + return 1; /*I/O space*/ + case 0x11: + return ncr53c8xx_pci_bar[0].addr_regs[1]; + case 0x12: + return ncr53c8xx_pci_bar[0].addr_regs[2]; + case 0x13: + return ncr53c8xx_pci_bar[0].addr_regs[3]; + case 0x14: + return 0; /*Memory space*/ + case 0x15: + return ncr53c8xx_pci_bar[1].addr_regs[1]; + case 0x16: + return ncr53c8xx_pci_bar[1].addr_regs[2]; + case 0x17: + return ncr53c8xx_pci_bar[1].addr_regs[3]; + case 0x18: + return 0; /*Memory space*/ + case 0x19: + if (!dev->wide) + return 0; + return ncr53c8xx_pci_bar[2].addr_regs[1]; + case 0x1A: + if (!dev->wide) + return 0; + return ncr53c8xx_pci_bar[2].addr_regs[2]; + case 0x1B: + if (!dev->wide) + return 0; + return ncr53c8xx_pci_bar[2].addr_regs[3]; + case 0x2C: + return 0x00; + case 0x2D: + if (dev->wide) + return 0; + return 0x10; + case 0x2E: + if (dev->wide) + return 0; + return 0x01; + case 0x2F: + return 0x00; + case 0x30: + return ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01; + case 0x31: + return ncr53c8xx_pci_bar[3].addr_regs[1]; + case 0x32: + return ncr53c8xx_pci_bar[3].addr_regs[2]; + case 0x33: + return ncr53c8xx_pci_bar[3].addr_regs[3]; + case 0x3C: + return dev->irq; + case 0x3D: + return PCI_INTA; + case 0x3E: + return 0x11; + case 0x3F: + return 0x40; } - return(0); + return (0); } - static void ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)p; - uint8_t valxor; + ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + uint8_t valxor; ncr53c8xx_log("NCR53c8xx: Write value %02X to register %02X\n", val, addr & 0xff); if ((addr >= 0x80) && (addr <= 0xFF)) { - ncr53c8xx_reg_writeb(dev, addr & 0x7F, val); - return; + ncr53c8xx_reg_writeb(dev, addr & 0x7F, val); + return; } - switch (addr) - { - case 0x04: - valxor = (val & 0x57) ^ ncr53c8xx_pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) { - ncr53c8xx_io_remove(dev, dev->PCIBase, 0x0100); - if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) - ncr53c8xx_io_set(dev, dev->PCIBase, 0x0100); - } - if (valxor & PCI_COMMAND_MEM) { - ncr53c8xx_mem_disable(dev); - if ((dev->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) - ncr53c8xx_mem_set_addr(dev, dev->MMIOBase); - if (dev->wide) { - ncr53c8xx_ram_disable(dev); - if ((dev->RAMBase != 0) && (val & PCI_COMMAND_MEM)) - ncr53c8xx_ram_set_addr(dev, dev->RAMBase); - } - } - ncr53c8xx_pci_regs[addr] = val & 0x57; - break; + switch (addr) { + case 0x04: + valxor = (val & 0x57) ^ ncr53c8xx_pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) { + ncr53c8xx_io_remove(dev, dev->PCIBase, 0x0100); + if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) + ncr53c8xx_io_set(dev, dev->PCIBase, 0x0100); + } + if (valxor & PCI_COMMAND_MEM) { + ncr53c8xx_mem_disable(dev); + if ((dev->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) + ncr53c8xx_mem_set_addr(dev, dev->MMIOBase); + if (dev->wide) { + ncr53c8xx_ram_disable(dev); + if ((dev->RAMBase != 0) && (val & PCI_COMMAND_MEM)) + ncr53c8xx_ram_set_addr(dev, dev->RAMBase); + } + } + ncr53c8xx_pci_regs[addr] = val & 0x57; + break; - case 0x05: - ncr53c8xx_pci_regs[addr] = val & 0x01; - break; + case 0x05: + ncr53c8xx_pci_regs[addr] = val & 0x01; + break; - case 0x0C: - case 0x0D: - ncr53c8xx_pci_regs[addr] = val; - break; + case 0x0C: + case 0x0D: + ncr53c8xx_pci_regs[addr] = val; + break; - case 0x10: case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O. */ - ncr53c8xx_io_remove(dev, dev->PCIBase, 0x0100); - /* Then let's set the PCI regs. */ - ncr53c8xx_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[0].addr &= 0xff00; - dev->PCIBase = ncr53c8xx_pci_bar[0].addr; - /* Log the new base. */ - ncr53c8xx_log("NCR53c8xx: New I/O base is %04X\n" , dev->PCIBase); - /* We're done, so get out of the here. */ - if (ncr53c8xx_pci_regs[4] & PCI_COMMAND_IO) { - if (dev->PCIBase != 0) { - ncr53c8xx_io_set(dev, dev->PCIBase, 0x0100); - } - } - return; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O. */ + ncr53c8xx_io_remove(dev, dev->PCIBase, 0x0100); + /* Then let's set the PCI regs. */ + ncr53c8xx_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + ncr53c8xx_pci_bar[0].addr &= 0xff00; + dev->PCIBase = ncr53c8xx_pci_bar[0].addr; + /* Log the new base. */ + ncr53c8xx_log("NCR53c8xx: New I/O base is %04X\n", dev->PCIBase); + /* We're done, so get out of the here. */ + if (ncr53c8xx_pci_regs[4] & PCI_COMMAND_IO) { + if (dev->PCIBase != 0) { + ncr53c8xx_io_set(dev, dev->PCIBase, 0x0100); + } + } + return; - case 0x15: case 0x16: case 0x17: - /* MMIO Base set. */ - /* First, remove the old I/O. */ - ncr53c8xx_mem_disable(dev); - /* Then let's set the PCI regs. */ - ncr53c8xx_pci_bar[1].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[1].addr &= 0xffffc000; - dev->MMIOBase = ncr53c8xx_pci_bar[1].addr & 0xffffc000; - /* Log the new base. */ - ncr53c8xx_log("NCR53c8xx: New MMIO base is %08X\n" , dev->MMIOBase); - /* We're done, so get out of the here. */ - if (ncr53c8xx_pci_regs[4] & PCI_COMMAND_MEM) { - if (dev->MMIOBase != 0) - ncr53c8xx_mem_set_addr(dev, dev->MMIOBase); - } - return; + case 0x15: + case 0x16: + case 0x17: + /* MMIO Base set. */ + /* First, remove the old I/O. */ + ncr53c8xx_mem_disable(dev); + /* Then let's set the PCI regs. */ + ncr53c8xx_pci_bar[1].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + ncr53c8xx_pci_bar[1].addr &= 0xffffc000; + dev->MMIOBase = ncr53c8xx_pci_bar[1].addr & 0xffffc000; + /* Log the new base. */ + ncr53c8xx_log("NCR53c8xx: New MMIO base is %08X\n", dev->MMIOBase); + /* We're done, so get out of the here. */ + if (ncr53c8xx_pci_regs[4] & PCI_COMMAND_MEM) { + if (dev->MMIOBase != 0) + ncr53c8xx_mem_set_addr(dev, dev->MMIOBase); + } + return; - case 0x19: case 0x1A: case 0x1B: - if (!dev->wide) - return; - /* RAM Base set. */ - /* First, remove the old I/O. */ - ncr53c8xx_ram_disable(dev); - /* Then let's set the PCI regs. */ - ncr53c8xx_pci_bar[2].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[2].addr &= 0xfffff000; - dev->RAMBase = ncr53c8xx_pci_bar[2].addr & 0xfffff000; - /* Log the new base. */ - ncr53c8xx_log("NCR53c8xx: New RAM base is %08X\n" , dev->RAMBase); - /* We're done, so get out of the here. */ - if (ncr53c8xx_pci_regs[4] & PCI_COMMAND_MEM) { - if (dev->RAMBase != 0) - ncr53c8xx_ram_set_addr(dev, dev->RAMBase); - } - return; + case 0x19: + case 0x1A: + case 0x1B: + if (!dev->wide) + return; + /* RAM Base set. */ + /* First, remove the old I/O. */ + ncr53c8xx_ram_disable(dev); + /* Then let's set the PCI regs. */ + ncr53c8xx_pci_bar[2].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + ncr53c8xx_pci_bar[2].addr &= 0xfffff000; + dev->RAMBase = ncr53c8xx_pci_bar[2].addr & 0xfffff000; + /* Log the new base. */ + ncr53c8xx_log("NCR53c8xx: New RAM base is %08X\n", dev->RAMBase); + /* We're done, so get out of the here. */ + if (ncr53c8xx_pci_regs[4] & PCI_COMMAND_MEM) { + if (dev->RAMBase != 0) + ncr53c8xx_ram_set_addr(dev, dev->RAMBase); + } + return; - case 0x30: case 0x31: case 0x32: case 0x33: - if (dev->has_bios == 0) - return; - /* BIOS Base set. */ - /* First, remove the old I/O. */ - ncr53c8xx_bios_disable(dev); - /* Then let's set the PCI regs. */ - ncr53c8xx_pci_bar[3].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[3].addr &= (dev->bios_mask | 0x00000001); - dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & dev->bios_mask; - ncr53c8xx_log("BIOS BAR: %08X\n", dev->BIOSBase | ncr53c8xx_pci_bar[3].addr_regs[0]); - /* Log the new base. */ - ncr53c8xx_log("NCR53c8xx: New BIOS base is %08X\n" , dev->BIOSBase); - /* We're done, so get out of the here. */ - if (ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01) - ncr53c8xx_bios_set_addr(dev, dev->BIOSBase); - return; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + if (dev->has_bios == 0) + return; + /* BIOS Base set. */ + /* First, remove the old I/O. */ + ncr53c8xx_bios_disable(dev); + /* Then let's set the PCI regs. */ + ncr53c8xx_pci_bar[3].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + ncr53c8xx_pci_bar[3].addr &= (dev->bios_mask | 0x00000001); + dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & dev->bios_mask; + ncr53c8xx_log("BIOS BAR: %08X\n", dev->BIOSBase | ncr53c8xx_pci_bar[3].addr_regs[0]); + /* Log the new base. */ + ncr53c8xx_log("NCR53c8xx: New BIOS base is %08X\n", dev->BIOSBase); + /* We're done, so get out of the here. */ + if (ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01) + ncr53c8xx_bios_set_addr(dev, dev->BIOSBase); + return; - case 0x3C: - ncr53c8xx_pci_regs[addr] = val; - dev->irq = val; - return; + case 0x3C: + ncr53c8xx_pci_regs[addr] = val; + dev->irq = val; + return; } } - static void * ncr53c8xx_init(const device_t *info) { @@ -2518,72 +2493,72 @@ ncr53c8xx_init(const device_t *info) dev->bus = scsi_get_bus(); dev->chip_rev = 0; - dev->chip = info->local & 0xff; + dev->chip = info->local & 0xff; if ((dev->chip != CHIP_810) && (dev->chip != CHIP_820) && !(info->local & 0x8000)) { - dev->has_bios = device_get_config_int("bios"); + dev->has_bios = device_get_config_int("bios"); - /* We have to auto-patch the BIOS to have the correct PCI Device ID, because for some reason, they all ship with - the PCI Device ID set to that of the NCR 53c825, but for a machine BIOS to load the SCSI BIOS correctly, the - PCI Device ID in the BIOS' PCIR block must match the one returned in the PCI registers. */ - if (dev->has_bios == 2) { - rom_init(&dev->bios, SYM53C8XX_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - ncr53c8xx_log("BIOS v4.19: Old BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x0022], dev->bios.rom[0xffff]); - dev->bios.rom[0xffff] += (dev->bios.rom[0x0022] - dev->chip); - dev->bios.rom[0x0022] = dev->chip; - ncr53c8xx_log("BIOS v4.19: New BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x0022], dev->bios.rom[0xffff]); - } else if (dev->has_bios == 1) { - rom_init(&dev->bios, NCR53C8XX_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ncr53c8xx_log("BIOS v3.07: Old BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x3fcb], dev->bios.rom[0x3fff]); - dev->bios.rom[0x3fff] += (dev->bios.rom[0x3fcb] - dev->chip); - dev->bios.rom[0x3fcb] = dev->chip; - ncr53c8xx_log("BIOS v3.07: New BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x3fcb], dev->bios.rom[0x3fff]); - } + /* We have to auto-patch the BIOS to have the correct PCI Device ID, because for some reason, they all ship with + the PCI Device ID set to that of the NCR 53c825, but for a machine BIOS to load the SCSI BIOS correctly, the + PCI Device ID in the BIOS' PCIR block must match the one returned in the PCI registers. */ + if (dev->has_bios == 2) { + rom_init(&dev->bios, SYM53C8XX_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + ncr53c8xx_log("BIOS v4.19: Old BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x0022], dev->bios.rom[0xffff]); + dev->bios.rom[0xffff] += (dev->bios.rom[0x0022] - dev->chip); + dev->bios.rom[0x0022] = dev->chip; + ncr53c8xx_log("BIOS v4.19: New BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x0022], dev->bios.rom[0xffff]); + } else if (dev->has_bios == 1) { + rom_init(&dev->bios, NCR53C8XX_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + ncr53c8xx_log("BIOS v3.07: Old BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x3fcb], dev->bios.rom[0x3fff]); + dev->bios.rom[0x3fff] += (dev->bios.rom[0x3fcb] - dev->chip); + dev->bios.rom[0x3fcb] = dev->chip; + ncr53c8xx_log("BIOS v3.07: New BIOS CHIP ID: %02X, old BIOS checksum: %02X\n", dev->bios.rom[0x3fcb], dev->bios.rom[0x3fff]); + } } else - dev->has_bios = 0; + dev->has_bios = 0; if (info->local & 0x8000) - dev->pci_slot = pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); + dev->pci_slot = pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); else - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); + dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); if (dev->chip == CHIP_875) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c875.nvr"; - dev->wide = 1; + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c875.nvr"; + dev->wide = 1; } else if (dev->chip == CHIP_860) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c860.nvr"; - dev->wide = 1; + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c860.nvr"; + dev->wide = 1; } else if (dev->chip == CHIP_820) { - dev->nvr_path = "ncr53c820.nvr"; - dev->wide = 1; + dev->nvr_path = "ncr53c820.nvr"; + dev->wide = 1; } else if (dev->chip == CHIP_825) { - dev->chip_rev = 0x26; - dev->nvr_path = "ncr53c825a.nvr"; - dev->wide = 1; + dev->chip_rev = 0x26; + dev->nvr_path = "ncr53c825a.nvr"; + dev->wide = 1; } else if (dev->chip == CHIP_810) { - dev->nvr_path = "ncr53c810.nvr"; - dev->wide = 0; + dev->nvr_path = "ncr53c810.nvr"; + dev->wide = 0; } else if (dev->chip == CHIP_815) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c815.nvr"; - dev->wide = 0; + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c815.nvr"; + dev->wide = 0; } ncr53c8xx_pci_bar[0].addr_regs[0] = 1; ncr53c8xx_pci_bar[1].addr_regs[0] = 0; - ncr53c8xx_pci_regs[0x04] = 3; + ncr53c8xx_pci_regs[0x04] = 3; if (dev->has_bios == 2) { - ncr53c8xx_pci_bar[3].addr = 0xffff0000; - dev->bios_mask = 0xffff0000; + ncr53c8xx_pci_bar[3].addr = 0xffff0000; + dev->bios_mask = 0xffff0000; } else if (dev->has_bios == 1) { - ncr53c8xx_pci_bar[3].addr = 0xffffc000; - dev->bios_mask = 0xffffc000; + ncr53c8xx_pci_bar[3].addr = 0xffffc000; + dev->bios_mask = 0xffffc000; } else { - ncr53c8xx_pci_bar[3].addr = 0x00000000; - dev->bios_mask = 0x00000000; + ncr53c8xx_pci_bar[3].addr = 0x00000000; + dev->bios_mask = 0x00000000; } ncr53c8xx_mem_init(dev, 0x0fffff00); @@ -2592,14 +2567,14 @@ ncr53c8xx_init(const device_t *info) ncr53c8xx_pci_bar[2].addr_regs[0] = 0; if (dev->wide) { - ncr53c8xx_ram_init(dev, 0x0ffff000); - ncr53c8xx_ram_disable(dev); + ncr53c8xx_ram_init(dev, 0x0ffff000); + ncr53c8xx_ram_disable(dev); } if (dev->has_bios) - ncr53c8xx_bios_disable(dev); + ncr53c8xx_bios_disable(dev); - dev->i2c = i2c_gpio_init("nvr_ncr53c8xx"); + dev->i2c = i2c_gpio_init("nvr_ncr53c8xx"); dev->eeprom = i2c_eeprom_init(i2c_gpio_get_bus(dev->i2c), 0x50, dev->nvram, sizeof(dev->nvram), 1); /* Load the serial EEPROM. */ @@ -2609,32 +2584,31 @@ ncr53c8xx_init(const device_t *info) timer_add(&dev->timer, ncr53c8xx_callback, dev, 0); - return(dev); + return (dev); } - static void ncr53c8xx_close(void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *)priv; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; if (dev) { - if (dev->eeprom) - i2c_eeprom_close(dev->eeprom); + if (dev->eeprom) + i2c_eeprom_close(dev->eeprom); - if (dev->i2c) - i2c_gpio_close(dev->i2c); + if (dev->i2c) + i2c_gpio_close(dev->i2c); - /* Save the serial EEPROM. */ - ncr53c8xx_eeprom(dev, 1); + /* Save the serial EEPROM. */ + ncr53c8xx_eeprom(dev, 1); - free(dev); - dev = NULL; + free(dev); + dev = NULL; } } static const device_config_t ncr53c8xx_pci_config[] = { -// clang-format off + // clang-format off { .name = "bios", .description = "BIOS", @@ -2655,99 +2629,99 @@ static const device_config_t ncr53c8xx_pci_config[] = { }; const device_t ncr53c810_pci_device = { - .name = "NCR 53c810", + .name = "NCR 53c810", .internal_name = "ncr53c810", - .flags = DEVICE_PCI, - .local = CHIP_810, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_810, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ncr53c810_onboard_pci_device = { - .name = "NCR 53c810 On-Board", + .name = "NCR 53c810 On-Board", .internal_name = "ncr53c810_onboard", - .flags = DEVICE_PCI, - .local = 0x8001, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0x8001, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ncr53c815_pci_device = { - .name = "NCR 53c815", + .name = "NCR 53c815", .internal_name = "ncr53c815", - .flags = DEVICE_PCI, - .local = CHIP_815, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_815, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, + .force_redraw = NULL, ncr53c8xx_pci_config }; const device_t ncr53c820_pci_device = { - .name = "NCR 53c820", + .name = "NCR 53c820", .internal_name = "ncr53c820", - .flags = DEVICE_PCI, - .local = CHIP_820, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_820, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ncr53c825a_pci_device = { - .name = "NCR 53c825A", + .name = "NCR 53c825A", .internal_name = "ncr53c825a", - .flags = DEVICE_PCI, - .local = CHIP_825, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_825, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr53c8xx_pci_config + .force_redraw = NULL, + .config = ncr53c8xx_pci_config }; const device_t ncr53c860_pci_device = { - .name = "NCR 53c860", + .name = "NCR 53c860", .internal_name = "ncr53c860", - .flags = DEVICE_PCI, - .local = CHIP_860, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_860, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr53c8xx_pci_config + .force_redraw = NULL, + .config = ncr53c8xx_pci_config }; const device_t ncr53c875_pci_device = { - .name = "NCR 53c875", + .name = "NCR 53c875", .internal_name = "ncr53c875", - .flags = DEVICE_PCI, - .local = CHIP_875, - .init = ncr53c8xx_init, - .close = ncr53c8xx_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = CHIP_875, + .init = ncr53c8xx_init, + .close = ncr53c8xx_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr53c8xx_pci_config + .force_redraw = NULL, + .config = ncr53c8xx_pci_config }; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 3266dc802..109a699d9 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -47,98 +47,98 @@ #include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> -#define DC390_ROM "roms/scsi/esp_pci/INT13.BIN" +#define DC390_ROM "roms/scsi/esp_pci/INT13.BIN" -#define ESP_REGS 16 -#define ESP_FIFO_SZ 16 -#define ESP_CMDFIFO_SZ 32 +#define ESP_REGS 16 +#define ESP_FIFO_SZ 16 +#define ESP_CMDFIFO_SZ 32 -#define ESP_TCLO 0x0 -#define ESP_TCMID 0x1 -#define ESP_FIFO 0x2 -#define ESP_CMD 0x3 -#define ESP_RSTAT 0x4 -#define ESP_WBUSID 0x4 -#define ESP_RINTR 0x5 -#define ESP_WSEL 0x5 -#define ESP_RSEQ 0x6 -#define ESP_WSYNTP 0x6 -#define ESP_RFLAGS 0x7 -#define ESP_WSYNO 0x7 -#define ESP_CFG1 0x8 -#define ESP_RRES1 0x9 -#define ESP_WCCF 0x9 -#define ESP_RRES2 0xa -#define ESP_WTEST 0xa -#define ESP_CFG2 0xb -#define ESP_CFG3 0xc -#define ESP_RES3 0xd -#define ESP_TCHI 0xe -#define ESP_RES4 0xf +#define ESP_TCLO 0x0 +#define ESP_TCMID 0x1 +#define ESP_FIFO 0x2 +#define ESP_CMD 0x3 +#define ESP_RSTAT 0x4 +#define ESP_WBUSID 0x4 +#define ESP_RINTR 0x5 +#define ESP_WSEL 0x5 +#define ESP_RSEQ 0x6 +#define ESP_WSYNTP 0x6 +#define ESP_RFLAGS 0x7 +#define ESP_WSYNO 0x7 +#define ESP_CFG1 0x8 +#define ESP_RRES1 0x9 +#define ESP_WCCF 0x9 +#define ESP_RRES2 0xa +#define ESP_WTEST 0xa +#define ESP_CFG2 0xb +#define ESP_CFG3 0xc +#define ESP_RES3 0xd +#define ESP_TCHI 0xe +#define ESP_RES4 0xf -#define CMD_DMA 0x80 -#define CMD_CMD 0x7f +#define CMD_DMA 0x80 +#define CMD_CMD 0x7f -#define CMD_NOP 0x00 -#define CMD_FLUSH 0x01 -#define CMD_RESET 0x02 -#define CMD_BUSRESET 0x03 -#define CMD_TI 0x10 -#define CMD_ICCS 0x11 -#define CMD_MSGACC 0x12 -#define CMD_PAD 0x18 -#define CMD_SATN 0x1a -#define CMD_RSTATN 0x1b -#define CMD_SEL 0x41 -#define CMD_SELATN 0x42 -#define CMD_SELATNS 0x43 -#define CMD_ENSEL 0x44 -#define CMD_DISSEL 0x45 +#define CMD_NOP 0x00 +#define CMD_FLUSH 0x01 +#define CMD_RESET 0x02 +#define CMD_BUSRESET 0x03 +#define CMD_TI 0x10 +#define CMD_ICCS 0x11 +#define CMD_MSGACC 0x12 +#define CMD_PAD 0x18 +#define CMD_SATN 0x1a +#define CMD_RSTATN 0x1b +#define CMD_SEL 0x41 +#define CMD_SELATN 0x42 +#define CMD_SELATNS 0x43 +#define CMD_ENSEL 0x44 +#define CMD_DISSEL 0x45 -#define STAT_DO 0x00 -#define STAT_DI 0x01 -#define STAT_CD 0x02 -#define STAT_ST 0x03 -#define STAT_MO 0x06 -#define STAT_MI 0x07 -#define STAT_PIO_MASK 0x06 +#define STAT_DO 0x00 +#define STAT_DI 0x01 +#define STAT_CD 0x02 +#define STAT_ST 0x03 +#define STAT_MO 0x06 +#define STAT_MI 0x07 +#define STAT_PIO_MASK 0x06 -#define STAT_TC 0x10 -#define STAT_PE 0x20 -#define STAT_GE 0x40 -#define STAT_INT 0x80 +#define STAT_TC 0x10 +#define STAT_PE 0x20 +#define STAT_GE 0x40 +#define STAT_INT 0x80 -#define BUSID_DID 0x07 +#define BUSID_DID 0x07 -#define INTR_FC 0x08 -#define INTR_BS 0x10 -#define INTR_DC 0x20 -#define INTR_RST 0x80 +#define INTR_FC 0x08 +#define INTR_BS 0x10 +#define INTR_DC 0x20 +#define INTR_RST 0x80 -#define SEQ_0 0x0 -#define SEQ_MO 0x1 -#define SEQ_CD 0x4 +#define SEQ_0 0x0 +#define SEQ_MO 0x1 +#define SEQ_CD 0x4 -#define CFG1_RESREPT 0x40 +#define CFG1_RESREPT 0x40 -#define TCHI_FAS100A 0x04 -#define TCHI_AM53C974 0x12 +#define TCHI_FAS100A 0x04 +#define TCHI_AM53C974 0x12 -#define DMA_CMD 0x0 -#define DMA_STC 0x1 -#define DMA_SPA 0x2 -#define DMA_WBC 0x3 -#define DMA_WAC 0x4 -#define DMA_STAT 0x5 -#define DMA_SMDLA 0x6 -#define DMA_WMAC 0x7 +#define DMA_CMD 0x0 +#define DMA_STC 0x1 +#define DMA_SPA 0x2 +#define DMA_WBC 0x3 +#define DMA_WAC 0x4 +#define DMA_STAT 0x5 +#define DMA_SMDLA 0x6 +#define DMA_WMAC 0x7 -#define DMA_CMD_MASK 0x03 -#define DMA_CMD_DIAG 0x04 -#define DMA_CMD_MDL 0x10 -#define DMA_CMD_INTE_P 0x20 -#define DMA_CMD_INTE_D 0x40 -#define DMA_CMD_DIR 0x80 +#define DMA_CMD_MASK 0x03 +#define DMA_CMD_DIAG 0x04 +#define DMA_CMD_MDL 0x10 +#define DMA_CMD_INTE_P 0x20 +#define DMA_CMD_INTE_D 0x40 +#define DMA_CMD_DIR 0x80 #define DMA_STAT_PWDN 0x01 #define DMA_STAT_ERROR 0x02 @@ -147,37 +147,37 @@ #define DMA_STAT_SCSIINT 0x10 #define DMA_STAT_BCMBLT 0x20 -#define SBAC_STATUS (1 << 24) -#define SBAC_PABTEN (1 << 25) +#define SBAC_STATUS (1 << 24) +#define SBAC_PABTEN (1 << 25) typedef struct { mem_mapping_t mmio_mapping; - mem_mapping_t ram_mapping; - char *nvr_path; - uint8_t pci_slot; - int has_bios; - int BIOSBase; - int MMIOBase; - rom_t bios; - ati_eeprom_t eeprom; - int PCIBase; + mem_mapping_t ram_mapping; + char *nvr_path; + uint8_t pci_slot; + int has_bios; + int BIOSBase; + int MMIOBase; + rom_t bios; + ati_eeprom_t eeprom; + int PCIBase; - uint8_t rregs[ESP_REGS]; - uint8_t wregs[ESP_REGS]; - int irq; - int tchi_written; + uint8_t rregs[ESP_REGS]; + uint8_t wregs[ESP_REGS]; + int irq; + int tchi_written; uint32_t ti_size; uint32_t status; uint32_t dma; - Fifo8 fifo; - uint8_t bus; - uint8_t id, lun; - Fifo8 cmdfifo; + Fifo8 fifo; + uint8_t bus; + uint8_t id, lun; + Fifo8 cmdfifo; uint32_t do_cmd; - uint8_t cmdfifo_cdb_offset; + uint8_t cmdfifo_cdb_offset; int32_t xfer_counter; - int dma_enabled; + int dma_enabled; uint32_t buffer_pos; uint32_t dma_regs[8]; @@ -187,41 +187,39 @@ typedef struct { pc_timer_t timer; - int mca; - uint16_t Base; - uint8_t HostID, DmaChannel; + int mca; + uint16_t Base; + uint8_t HostID, DmaChannel; - struct - { - uint8_t mode; - uint8_t status; - int pos; - } dma_86c01; + struct + { + uint8_t mode; + uint8_t status; + int pos; + } dma_86c01; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; } esp_t; #define READ_FROM_DEVICE 1 #define WRITE_TO_DEVICE 0 - #ifdef ENABLE_ESP_LOG int esp_do_log = ENABLE_ESP_LOG; - static void esp_log(const char *fmt, ...) { va_list ap; if (esp_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define esp_log(fmt, ...) +# define esp_log(fmt, ...) #endif static void esp_dma_enable(esp_t *dev, int level); @@ -238,42 +236,42 @@ static void handle_ti(void *priv); static void esp_irq(esp_t *dev, int level) { - if (dev->mca) { - if (level) { - picint(1 << dev->irq); - dev->dma_86c01.status |= 0x01; - esp_log("Raising IRQ...\n"); - } else { - picintc(1 << dev->irq); - dev->dma_86c01.status &= ~0x01; - esp_log("Lowering IRQ...\n"); - } - } else { - if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); - esp_log("Raising IRQ...\n"); - } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); - esp_log("Lowering IRQ...\n"); - } - } + if (dev->mca) { + if (level) { + picint(1 << dev->irq); + dev->dma_86c01.status |= 0x01; + esp_log("Raising IRQ...\n"); + } else { + picintc(1 << dev->irq); + dev->dma_86c01.status &= ~0x01; + esp_log("Lowering IRQ...\n"); + } + } else { + if (level) { + pci_set_irq(dev->pci_slot, PCI_INTA); + esp_log("Raising IRQ...\n"); + } else { + pci_clear_irq(dev->pci_slot, PCI_INTA); + esp_log("Lowering IRQ...\n"); + } + } } static void esp_raise_irq(esp_t *dev) { - if (!(dev->rregs[ESP_RSTAT] & STAT_INT)) { - dev->rregs[ESP_RSTAT] |= STAT_INT; - esp_irq(dev, 1); + if (!(dev->rregs[ESP_RSTAT] & STAT_INT)) { + dev->rregs[ESP_RSTAT] |= STAT_INT; + esp_irq(dev, 1); } } static void esp_lower_irq(esp_t *dev) { - if (dev->rregs[ESP_RSTAT] & STAT_INT) { - dev->rregs[ESP_RSTAT] &= ~STAT_INT; - esp_irq(dev, 0); + if (dev->rregs[ESP_RSTAT] & STAT_INT) { + dev->rregs[ESP_RSTAT] &= ~STAT_INT; + esp_irq(dev, 0); } } @@ -301,7 +299,7 @@ static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen) { const uint8_t *buf; - uint32_t n; + uint32_t n; if (maxlen == 0) { return 0; @@ -330,9 +328,9 @@ esp_get_tc(esp_t *dev) static void esp_set_tc(esp_t *dev, uint32_t dmalen) { - dev->rregs[ESP_TCLO] = dmalen; + dev->rregs[ESP_TCLO] = dmalen; dev->rregs[ESP_TCMID] = dmalen >> 8; - dev->rregs[ESP_TCHI] = dmalen >> 16; + dev->rregs[ESP_TCHI] = dmalen >> 16; } static uint32_t @@ -351,10 +349,10 @@ static void esp_dma_done(esp_t *dev) { dev->rregs[ESP_RSTAT] |= STAT_TC; - dev->rregs[ESP_RINTR] = INTR_BS; - dev->rregs[ESP_RSEQ] = 0; + dev->rregs[ESP_RINTR] = INTR_BS; + dev->rregs[ESP_RSEQ] = 0; dev->rregs[ESP_RFLAGS] = 0; - esp_set_tc(dev, 0); + esp_set_tc(dev, 0); esp_log("ESP DMA Finished\n"); esp_raise_irq(dev); } @@ -362,31 +360,31 @@ esp_dma_done(esp_t *dev) static uint32_t esp_get_cmd(esp_t *dev, uint32_t maxlen) { - uint8_t buf[ESP_CMDFIFO_SZ]; + uint8_t buf[ESP_CMDFIFO_SZ]; uint32_t dmalen, n; dev->id = dev->wregs[ESP_WBUSID] & BUSID_DID; if (dev->dma) { dmalen = MIN(esp_get_tc(dev), maxlen); - esp_log("ESP Get data, dmalen = %d\n", dmalen); - if (dmalen == 0) - return 0; - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < dmalen) { - int val = dma_channel_read(dev->DmaChannel); - buf[dev->dma_86c01.pos++] = val & 0xff; - } - dev->dma_86c01.pos = 0; - dma_set_drq(dev->DmaChannel, 0); - } else { - esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE); - dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); - fifo8_push_all(&dev->cmdfifo, buf, dmalen); - } + esp_log("ESP Get data, dmalen = %d\n", dmalen); + if (dmalen == 0) + return 0; + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < dmalen) { + int val = dma_channel_read(dev->DmaChannel); + buf[dev->dma_86c01.pos++] = val & 0xff; + } + dev->dma_86c01.pos = 0; + dma_set_drq(dev->DmaChannel, 0); + } else { + esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE); + dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); + fifo8_push_all(&dev->cmdfifo, buf, dmalen); + } } else { dmalen = MIN(fifo8_num_used(&dev->fifo), maxlen); - esp_log("ESP Get command, dmalen = %i\n", dmalen); + esp_log("ESP Get command, dmalen = %i\n", dmalen); if (dmalen == 0) { return 0; } @@ -396,7 +394,7 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen) } dev->ti_size = 0; - fifo8_reset(&dev->fifo); + fifo8_reset(&dev->fifo); dev->rregs[ESP_RINTR] |= INTR_FC; dev->rregs[ESP_RSEQ] = SEQ_CD; @@ -407,129 +405,129 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen) static void esp_do_command_phase(esp_t *dev) { - uint32_t cmdlen; - uint8_t buf[ESP_CMDFIFO_SZ]; + uint32_t cmdlen; + uint8_t buf[ESP_CMDFIFO_SZ]; scsi_device_t *sd; sd = &scsi_devices[dev->bus][dev->id]; - sd->buffer_length = -1; + sd->buffer_length = -1; - cmdlen = fifo8_num_used(&dev->cmdfifo); - if (!cmdlen) - return; + cmdlen = fifo8_num_used(&dev->cmdfifo); + if (!cmdlen) + return; - esp_fifo_pop_buf(&dev->cmdfifo, buf, cmdlen); + esp_fifo_pop_buf(&dev->cmdfifo, buf, cmdlen); - for (int i = 0; i < cmdlen; i++) - esp_log("CDB[%i] = %02x\n", i, buf[i]); + for (int i = 0; i < cmdlen; i++) + esp_log("CDB[%i] = %02x\n", i, buf[i]); scsi_device_command_phase0(sd, buf); - dev->buffer_pos = 0; - dev->ti_size = sd->buffer_length; + dev->buffer_pos = 0; + dev->ti_size = sd->buffer_length; dev->xfer_counter = sd->buffer_length; esp_log("ESP SCSI Command = 0x%02x, ID = %d, LUN = %d, len = %d\n", buf[0], dev->id, dev->lun, sd->buffer_length); - fifo8_reset(&dev->cmdfifo); + fifo8_reset(&dev->cmdfifo); if (sd->buffer_length > 0) { - /* This should be set to the underlying device's buffer by command phase 0. */ - dev->rregs[ESP_RSTAT] = STAT_TC; - dev->rregs[ESP_RSEQ] = SEQ_CD; + /* This should be set to the underlying device's buffer by command phase 0. */ + dev->rregs[ESP_RSTAT] = STAT_TC; + dev->rregs[ESP_RSEQ] = SEQ_CD; - if (sd->phase == SCSI_PHASE_DATA_IN) { - dev->rregs[ESP_RSTAT] |= STAT_DI; - esp_log("ESP Data In\n"); - esp_timer_on(dev, sd, scsi_device_get_callback(sd)); - } else if (sd->phase == SCSI_PHASE_DATA_OUT) { - dev->rregs[ESP_RSTAT] |= STAT_DO; - esp_log("ESP Data Out\n"); - dev->ti_size = -sd->buffer_length; - esp_timer_on(dev, sd, scsi_device_get_callback(sd)); - } - esp_log("ESP SCSI Start reading/writing\n"); - esp_do_dma(dev, sd); + if (sd->phase == SCSI_PHASE_DATA_IN) { + dev->rregs[ESP_RSTAT] |= STAT_DI; + esp_log("ESP Data In\n"); + esp_timer_on(dev, sd, scsi_device_get_callback(sd)); + } else if (sd->phase == SCSI_PHASE_DATA_OUT) { + dev->rregs[ESP_RSTAT] |= STAT_DO; + esp_log("ESP Data Out\n"); + dev->ti_size = -sd->buffer_length; + esp_timer_on(dev, sd, scsi_device_get_callback(sd)); + } + esp_log("ESP SCSI Start reading/writing\n"); + esp_do_dma(dev, sd); } else { - esp_log("ESP SCSI Command with no length\n"); - if (dev->mca) { - if (buf[0] == 0x43) { - dev->rregs[ESP_RSTAT] = STAT_DI | STAT_TC; - dev->rregs[ESP_RSEQ] = SEQ_CD; - esp_do_dma(dev, sd); - } else - esp_command_complete(dev, sd->status); - } else - esp_pci_command_complete(dev, sd->status); + esp_log("ESP SCSI Command with no length\n"); + if (dev->mca) { + if (buf[0] == 0x43) { + dev->rregs[ESP_RSTAT] = STAT_DI | STAT_TC; + dev->rregs[ESP_RSEQ] = SEQ_CD; + esp_do_dma(dev, sd); + } else + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); } scsi_device_identify(sd, SCSI_LUN_USE_CDB); - dev->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; - esp_raise_irq(dev); + dev->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; + esp_raise_irq(dev); } static void esp_do_message_phase(esp_t *dev) { - int len; - uint8_t message; + int len; + uint8_t message; if (dev->cmdfifo_cdb_offset) { - message = esp_fifo_pop(&dev->cmdfifo); + message = esp_fifo_pop(&dev->cmdfifo); - dev->lun = message & 7; + dev->lun = message & 7; dev->cmdfifo_cdb_offset--; - if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) { - /* We only support LUN 0 */ - esp_log("LUN = %i\n", dev->lun); - dev->rregs[ESP_RSTAT] = 0; - dev->rregs[ESP_RINTR] = INTR_DC; - dev->rregs[ESP_RSEQ] = SEQ_0; - esp_raise_irq(dev); - fifo8_reset(&dev->cmdfifo); - return; - } + if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) { + /* We only support LUN 0 */ + esp_log("LUN = %i\n", dev->lun); + dev->rregs[ESP_RSTAT] = 0; + dev->rregs[ESP_RINTR] = INTR_DC; + dev->rregs[ESP_RSEQ] = SEQ_0; + esp_raise_irq(dev); + fifo8_reset(&dev->cmdfifo); + return; + } - scsi_device_identify(&scsi_devices[dev->bus][dev->id], dev->lun); + scsi_device_identify(&scsi_devices[dev->bus][dev->id], dev->lun); } - esp_log("CDB offset = %i\n", dev->cmdfifo_cdb_offset); + esp_log("CDB offset = %i\n", dev->cmdfifo_cdb_offset); - if (dev->cmdfifo_cdb_offset) { - len = MIN(dev->cmdfifo_cdb_offset, fifo8_num_used(&dev->cmdfifo)); + if (dev->cmdfifo_cdb_offset) { + len = MIN(dev->cmdfifo_cdb_offset, fifo8_num_used(&dev->cmdfifo)); esp_fifo_pop_buf(&dev->cmdfifo, NULL, len); dev->cmdfifo_cdb_offset = 0; - } + } } static void esp_do_cmd(esp_t *dev) { - esp_do_message_phase(dev); - if (dev->cmdfifo_cdb_offset == 0) - esp_do_command_phase(dev); + esp_do_message_phase(dev); + if (dev->cmdfifo_cdb_offset == 0) + esp_do_command_phase(dev); } static void esp_dma_enable(esp_t *dev, int level) { if (level) { - esp_log("ESP DMA Enabled\n"); - dev->dma_enabled = 1; - dev->dma_86c01.status |= 0x02; - if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) { - timer_on_auto(&dev->timer, 40.0); - } else { - esp_log("Period = %lf\n", dev->period); - timer_on_auto(&dev->timer, dev->period); - } + esp_log("ESP DMA Enabled\n"); + dev->dma_enabled = 1; + dev->dma_86c01.status |= 0x02; + if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) { + timer_on_auto(&dev->timer, 40.0); + } else { + esp_log("Period = %lf\n", dev->period); + timer_on_auto(&dev->timer, dev->period); + } } else { - esp_log("ESP DMA Disabled\n"); - dev->dma_enabled = 0; - dev->dma_86c01.status &= ~0x02; + esp_log("ESP DMA Disabled\n"); + dev->dma_enabled = 0; + dev->dma_86c01.status &= ~0x02; } } @@ -539,11 +537,11 @@ esp_hard_reset(esp_t *dev) memset(dev->rregs, 0, ESP_REGS); memset(dev->wregs, 0, ESP_REGS); dev->tchi_written = 0; - dev->ti_size = 0; + dev->ti_size = 0; fifo8_reset(&dev->fifo); - fifo8_reset(&dev->cmdfifo); - dev->dma = 0; - dev->do_cmd = 0; + fifo8_reset(&dev->cmdfifo); + dev->dma = 0; + dev->do_cmd = 0; dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; esp_log("ESP Reset\n"); timer_stop(&dev->timer); @@ -557,263 +555,262 @@ esp_do_nodma(esp_t *dev, scsi_device_t *sd) esp_log("ESP SCSI Actual FIFO len = %d\n", dev->xfer_counter); if (dev->do_cmd) { - esp_log("ESP Command on FIFO\n"); - dev->ti_size = 0; + esp_log("ESP Command on FIFO\n"); + dev->ti_size = 0; - if ((dev->rregs[ESP_RSTAT] & 7) == STAT_CD) { - if (dev->cmdfifo_cdb_offset == fifo8_num_used(&dev->cmdfifo)) { - esp_log("CDB offset = %i used return\n", dev->cmdfifo_cdb_offset); - return; - } + if ((dev->rregs[ESP_RSTAT] & 7) == STAT_CD) { + if (dev->cmdfifo_cdb_offset == fifo8_num_used(&dev->cmdfifo)) { + esp_log("CDB offset = %i used return\n", dev->cmdfifo_cdb_offset); + return; + } - dev->do_cmd = 0; - esp_do_cmd(dev); - } else { - dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo);; - esp_log("CDB offset = %i used\n", dev->cmdfifo_cdb_offset); + dev->do_cmd = 0; + esp_do_cmd(dev); + } else { + dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); + ; + esp_log("CDB offset = %i used\n", dev->cmdfifo_cdb_offset); - dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; - dev->rregs[ESP_RSEQ] = SEQ_CD; - dev->rregs[ESP_RINTR] |= INTR_BS; - esp_raise_irq(dev); - } - return; + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } + return; } if (dev->xfer_counter == 0) { - /* Wait until data is available. */ - esp_log("(ID=%02i LUN=%02i): FIFO no data available\n", dev->id, dev->lun); - return; + /* Wait until data is available. */ + esp_log("(ID=%02i LUN=%02i): FIFO no data available\n", dev->id, dev->lun); + return; } esp_log("ESP FIFO = %d, buffer length = %d\n", dev->xfer_counter, sd->buffer_length); if (sd->phase == SCSI_PHASE_DATA_IN) { - if (fifo8_is_empty(&dev->fifo)) { - fifo8_push(&dev->fifo, sd->sc->temp_buffer[dev->buffer_pos]); - dev->buffer_pos++; - dev->ti_size--; - dev->xfer_counter--; - } + if (fifo8_is_empty(&dev->fifo)) { + fifo8_push(&dev->fifo, sd->sc->temp_buffer[dev->buffer_pos]); + dev->buffer_pos++; + dev->ti_size--; + dev->xfer_counter--; + } } else if (sd->phase == SCSI_PHASE_DATA_OUT) { count = MIN(fifo8_num_used(&dev->fifo), ESP_FIFO_SZ); esp_fifo_pop_buf(&dev->fifo, sd->sc->temp_buffer + dev->buffer_pos, count); - dev->buffer_pos += count; - dev->ti_size += count; - dev->xfer_counter -= count; + dev->buffer_pos += count; + dev->ti_size += count; + dev->xfer_counter -= count; } esp_log("ESP FIFO Transfer bytes = %d\n", dev->xfer_counter); if (dev->xfer_counter <= 0) { - if (sd->phase == SCSI_PHASE_DATA_OUT) { - if (dev->ti_size < 0) { - esp_log("ESP FIFO Keep writing\n"); - esp_do_nodma(dev, sd); - } else { - esp_log("ESP FIFO Write finished\n"); - scsi_device_command_phase1(sd); - if (dev->mca) { - esp_command_complete(dev, sd->status); - } else - esp_pci_command_complete(dev, sd->status); - } - } else if (sd->phase == SCSI_PHASE_DATA_IN) { - /* If there is still data to be read from the device then - complete the DMA operation immediately. Otherwise defer - until the scsi layer has completed. */ - if (dev->ti_size <= 0) { - esp_log("ESP FIFO Read finished\n"); - scsi_device_command_phase1(sd); - if (dev->mca) { - esp_command_complete(dev, sd->status); - } else - esp_pci_command_complete(dev, sd->status); - } else { - esp_log("ESP FIFO Keep reading\n"); - esp_do_nodma(dev, sd); - } - } + if (sd->phase == SCSI_PHASE_DATA_OUT) { + if (dev->ti_size < 0) { + esp_log("ESP FIFO Keep writing\n"); + esp_do_nodma(dev, sd); + } else { + esp_log("ESP FIFO Write finished\n"); + scsi_device_command_phase1(sd); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); + } + } else if (sd->phase == SCSI_PHASE_DATA_IN) { + /* If there is still data to be read from the device then + complete the DMA operation immediately. Otherwise defer + until the scsi layer has completed. */ + if (dev->ti_size <= 0) { + esp_log("ESP FIFO Read finished\n"); + scsi_device_command_phase1(sd); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); + } else { + esp_log("ESP FIFO Keep reading\n"); + esp_do_nodma(dev, sd); + } + } } else { - /* Partially filled a scsi buffer. Complete immediately. */ - esp_log("ESP SCSI Partially filled the FIFO buffer\n"); - dev->rregs[ESP_RINTR] |= INTR_BS; - esp_raise_irq(dev); + /* Partially filled a scsi buffer. Complete immediately. */ + esp_log("ESP SCSI Partially filled the FIFO buffer\n"); + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); } } - static void esp_do_dma(esp_t *dev, scsi_device_t *sd) { - uint8_t buf[ESP_CMDFIFO_SZ]; + uint8_t buf[ESP_CMDFIFO_SZ]; uint32_t tdbc; - int count; + int count; esp_log("ESP SCSI Actual DMA len = %d\n", esp_get_tc(dev)); if (!scsi_device_present(sd)) { - esp_log("ESP SCSI no devices on ID %d, LUN %d\n", dev->id, dev->lun); + esp_log("ESP SCSI no devices on ID %d, LUN %d\n", dev->id, dev->lun); /* No such drive */ dev->rregs[ESP_RSTAT] = 0; dev->rregs[ESP_RINTR] = INTR_DC; - dev->rregs[ESP_RSEQ] = SEQ_0; - esp_raise_irq(dev); - fifo8_reset(&dev->cmdfifo); - return; + dev->rregs[ESP_RSEQ] = SEQ_0; + esp_raise_irq(dev); + fifo8_reset(&dev->cmdfifo); + return; } else { - esp_log("ESP SCSI device found on ID %d, LUN %d\n", dev->id, dev->lun); + esp_log("ESP SCSI device found on ID %d, LUN %d\n", dev->id, dev->lun); } count = tdbc = esp_get_tc(dev); - if (dev->mca) { /*See the comment in the esp_do_busid_cmd() function.*/ - if (sd->buffer_length < 0) { - if (dev->dma_enabled) - goto done; - else - goto partial; - } - } + if (dev->mca) { /*See the comment in the esp_do_busid_cmd() function.*/ + if (sd->buffer_length < 0) { + if (dev->dma_enabled) + goto done; + else + goto partial; + } + } if (dev->do_cmd) { - esp_log("ESP Command on DMA\n"); - count = MIN(count, fifo8_num_free(&dev->cmdfifo)); - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < count) { - dma_channel_write(dev->DmaChannel, buf[dev->dma_86c01.pos]); - dev->dma_86c01.pos++; - } - dev->dma_86c01.pos = 0; - dma_set_drq(dev->DmaChannel, 0); - } else - esp_pci_dma_memory_rw(dev, buf, count, READ_FROM_DEVICE); - fifo8_push_all(&dev->cmdfifo, buf, count); - dev->ti_size = 0; + esp_log("ESP Command on DMA\n"); + count = MIN(count, fifo8_num_free(&dev->cmdfifo)); + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < count) { + dma_channel_write(dev->DmaChannel, buf[dev->dma_86c01.pos]); + dev->dma_86c01.pos++; + } + dev->dma_86c01.pos = 0; + dma_set_drq(dev->DmaChannel, 0); + } else + esp_pci_dma_memory_rw(dev, buf, count, READ_FROM_DEVICE); + fifo8_push_all(&dev->cmdfifo, buf, count); + dev->ti_size = 0; - if ((dev->rregs[ESP_RSTAT] & 7) == STAT_CD) { - if (dev->cmdfifo_cdb_offset == fifo8_num_used(&dev->cmdfifo)) - return; + if ((dev->rregs[ESP_RSTAT] & 7) == STAT_CD) { + if (dev->cmdfifo_cdb_offset == fifo8_num_used(&dev->cmdfifo)) + return; - dev->do_cmd = 0; - esp_do_cmd(dev); - } else { - dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); + dev->do_cmd = 0; + esp_do_cmd(dev); + } else { + dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); - dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; - dev->rregs[ESP_RSEQ] = SEQ_CD; - dev->rregs[ESP_RINTR] |= INTR_BS; - esp_raise_irq(dev); - } - return; + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } + return; } if (dev->xfer_counter == 0) { - /* Wait until data is available. */ - esp_log("(ID=%02i LUN=%02i): DMA no data available\n", dev->id, dev->lun); - return; + /* Wait until data is available. */ + esp_log("(ID=%02i LUN=%02i): DMA no data available\n", dev->id, dev->lun); + return; } esp_log("ESP SCSI dmaleft = %d, async_len = %i, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length); /* Make sure count is never bigger than buffer_length. */ if (count > dev->xfer_counter) - count = dev->xfer_counter; + count = dev->xfer_counter; if (sd->phase == SCSI_PHASE_DATA_IN) { - esp_log("ESP SCSI Read, dma cnt = %i, ti size = %i, positive len = %i\n", esp_get_tc(dev), dev->ti_size, count); - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < count) { - dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); - esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); - dev->dma_86c01.pos++; - } - dev->dma_86c01.pos = 0; - dma_set_drq(dev->DmaChannel, 0); - } else { - esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, READ_FROM_DEVICE); - } + esp_log("ESP SCSI Read, dma cnt = %i, ti size = %i, positive len = %i\n", esp_get_tc(dev), dev->ti_size, count); + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < count) { + dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); + esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); + dev->dma_86c01.pos++; + } + dev->dma_86c01.pos = 0; + dma_set_drq(dev->DmaChannel, 0); + } else { + esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, READ_FROM_DEVICE); + } } else if (sd->phase == SCSI_PHASE_DATA_OUT) { - esp_log("ESP SCSI Write, negative len = %i, ti size = %i, dma cnt = %i\n", count, -dev->ti_size, esp_get_tc(dev)); - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < count) { - int val = dma_channel_read(dev->DmaChannel); - esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); - sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff; - dev->dma_86c01.pos++; - } - dma_set_drq(dev->DmaChannel, 0); - dev->dma_86c01.pos = 0; - } else - esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, WRITE_TO_DEVICE); + esp_log("ESP SCSI Write, negative len = %i, ti size = %i, dma cnt = %i\n", count, -dev->ti_size, esp_get_tc(dev)); + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < count) { + int val = dma_channel_read(dev->DmaChannel); + esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); + sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff; + dev->dma_86c01.pos++; + } + dma_set_drq(dev->DmaChannel, 0); + dev->dma_86c01.pos = 0; + } else + esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, WRITE_TO_DEVICE); } - esp_set_tc(dev, esp_get_tc(dev) - count); + esp_set_tc(dev, esp_get_tc(dev) - count); dev->buffer_pos += count; dev->xfer_counter -= count; if (sd->phase == SCSI_PHASE_DATA_IN) { - dev->ti_size -= count; + dev->ti_size -= count; } else if (sd->phase == SCSI_PHASE_DATA_OUT) { - dev->ti_size += count; + dev->ti_size += count; } esp_log("ESP SCSI Transfer bytes = %d\n", dev->xfer_counter); if (dev->xfer_counter <= 0) { - if (sd->phase == SCSI_PHASE_DATA_OUT) { - if (dev->ti_size < 0) { - esp_log("ESP SCSI Keep writing\n"); - esp_do_dma(dev, sd); - } else { - esp_log("ESP SCSI Write finished\n"); - scsi_device_command_phase1(sd); - if (dev->mca) { - esp_command_complete(dev, sd->status); - } else - esp_pci_command_complete(dev, sd->status); - } - } else if (sd->phase == SCSI_PHASE_DATA_IN) { - /* If there is still data to be read from the device then - complete the DMA operation immediately. Otherwise defer - until the scsi layer has completed. */ - if (dev->ti_size <= 0) { + if (sd->phase == SCSI_PHASE_DATA_OUT) { + if (dev->ti_size < 0) { + esp_log("ESP SCSI Keep writing\n"); + esp_do_dma(dev, sd); + } else { + esp_log("ESP SCSI Write finished\n"); + scsi_device_command_phase1(sd); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); + } + } else if (sd->phase == SCSI_PHASE_DATA_IN) { + /* If there is still data to be read from the device then + complete the DMA operation immediately. Otherwise defer + until the scsi layer has completed. */ + if (dev->ti_size <= 0) { done: - esp_log("ESP SCSI Read finished\n"); - scsi_device_command_phase1(sd); - if (dev->mca) { - esp_command_complete(dev, sd->status); - } else - esp_pci_command_complete(dev, sd->status); - } else { - esp_log("ESP SCSI Keep reading\n"); - esp_do_dma(dev, sd); - } - } + esp_log("ESP SCSI Read finished\n"); + scsi_device_command_phase1(sd); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); + } else { + esp_log("ESP SCSI Keep reading\n"); + esp_do_dma(dev, sd); + } + } } else { - /* Partially filled a scsi buffer. Complete immediately. */ + /* Partially filled a scsi buffer. Complete immediately. */ partial: - esp_log("ESP SCSI Partially filled the SCSI buffer\n"); - esp_dma_done(dev); + esp_log("ESP SCSI Partially filled the SCSI buffer\n"); + esp_dma_done(dev); } } - static void esp_report_command_complete(esp_t *dev, uint32_t status) { esp_log("ESP Command complete\n"); - dev->ti_size = 0; - dev->status = status; + dev->ti_size = 0; + dev->status = status; dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; - esp_dma_done(dev); + esp_dma_done(dev); } /* Callback to indicate that the SCSI layer has completed a command. */ static void esp_command_complete(void *priv, uint32_t status) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; esp_report_command_complete(dev, status); } @@ -821,7 +818,7 @@ esp_command_complete(void *priv, uint32_t status) static void esp_pci_command_complete(void *priv, uint32_t status) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; esp_command_complete(dev, status); dev->dma_regs[DMA_WBC] = 0; @@ -831,121 +828,121 @@ esp_pci_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - if (dev->mca) { - /* Normal SCSI: 5000000 bytes per second */ - dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); - } else { - /* Fast SCSI: 10000000 bytes per second */ - dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); - } + if (dev->mca) { + /* Normal SCSI: 5000000 bytes per second */ + dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); + } else { + /* Fast SCSI: 10000000 bytes per second */ + dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + } - timer_on_auto(&dev->timer, dev->period + 40.0); + timer_on_auto(&dev->timer, dev->period + 40.0); } static void handle_ti(void *priv) { - esp_t *dev = (esp_t *)priv; - scsi_device_t *sd = &scsi_devices[dev->bus][dev->id]; + esp_t *dev = (esp_t *) priv; + scsi_device_t *sd = &scsi_devices[dev->bus][dev->id]; if (dev->dma) { - esp_log("ESP Handle TI, do data, minlen = %i\n", esp_get_tc(dev)); - esp_do_dma(dev, sd); + esp_log("ESP Handle TI, do data, minlen = %i\n", esp_get_tc(dev)); + esp_do_dma(dev, sd); } else { - esp_log("ESP Handle TI, do nodma, minlen = %i\n", dev->xfer_counter); - esp_do_nodma(dev, sd); + esp_log("ESP Handle TI, do nodma, minlen = %i\n", dev->xfer_counter); + esp_do_nodma(dev, sd); } } static void handle_s_without_atn(void *priv) { - esp_t *dev = (esp_t *)priv; - int len; + esp_t *dev = (esp_t *) priv; + int len; len = esp_get_cmd(dev, ESP_CMDFIFO_SZ); esp_log("ESP SEL w/o ATN len = %d, id = %d\n", len, dev->id); if (len > 0) { - dev->cmdfifo_cdb_offset = 0; - dev->do_cmd = 0; - esp_do_cmd(dev); + dev->cmdfifo_cdb_offset = 0; + dev->do_cmd = 0; + esp_do_cmd(dev); } else if (len == 0) { - dev->do_cmd = 1; + dev->do_cmd = 1; /* Target present, but no cmd yet - switch to command phase */ - dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RSEQ] = SEQ_CD; dev->rregs[ESP_RSTAT] = STAT_CD; - } + } } static void handle_satn(void *priv) { - esp_t *dev = (esp_t *)priv; - int len; + esp_t *dev = (esp_t *) priv; + int len; len = esp_get_cmd(dev, ESP_CMDFIFO_SZ); esp_log("ESP SEL with ATN len = %d, id = %d\n", len, dev->id); if (len > 0) { - dev->cmdfifo_cdb_offset = 1; - dev->do_cmd = 0; - esp_do_cmd(dev); + dev->cmdfifo_cdb_offset = 1; + dev->do_cmd = 0; + esp_do_cmd(dev); } else if (len == 0) { - dev->do_cmd = 1; - /* Target present, but no cmd yet - switch to command phase */ - dev->rregs[ESP_RSEQ] = SEQ_CD; - dev->rregs[ESP_RSTAT] = STAT_CD; - } + dev->do_cmd = 1; + /* Target present, but no cmd yet - switch to command phase */ + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RSTAT] = STAT_CD; + } } static void handle_satn_stop(void *priv) { - esp_t *dev = (esp_t *)priv; - int cmdlen; + esp_t *dev = (esp_t *) priv; + int cmdlen; cmdlen = esp_get_cmd(dev, 1); if (cmdlen > 0) { - dev->do_cmd = 1; - dev->cmdfifo_cdb_offset = 1; - dev->rregs[ESP_RSTAT] = STAT_MO; - dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; - dev->rregs[ESP_RSEQ] = SEQ_MO; - esp_log("ESP SCSI Command len = %d, raising IRQ\n", cmdlen); - esp_raise_irq(dev); + dev->do_cmd = 1; + dev->cmdfifo_cdb_offset = 1; + dev->rregs[ESP_RSTAT] = STAT_MO; + dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; + dev->rregs[ESP_RSEQ] = SEQ_MO; + esp_log("ESP SCSI Command len = %d, raising IRQ\n", cmdlen); + esp_raise_irq(dev); } else if (cmdlen == 0) { - dev->do_cmd = 1; - /* Target present, switch to message out phase */ - dev->rregs[ESP_RSEQ] = SEQ_MO; - dev->rregs[ESP_RSTAT] = STAT_MO; - } + dev->do_cmd = 1; + /* Target present, switch to message out phase */ + dev->rregs[ESP_RSEQ] = SEQ_MO; + dev->rregs[ESP_RSTAT] = STAT_MO; + } } static void esp_write_response(esp_t *dev) { - uint8_t buf[2]; + uint8_t buf[2]; buf[0] = dev->status; buf[1] = 0; if (dev->dma) { - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < 2) { - int val = dma_channel_read(dev->DmaChannel); - buf[dev->dma_86c01.pos++] = val & 0xff; - } - dev->dma_86c01.pos = 0; - dma_set_drq(dev->DmaChannel, 0); - } else - esp_pci_dma_memory_rw(dev, buf, 2, WRITE_TO_DEVICE); - dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; - dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; - dev->rregs[ESP_RSEQ] = SEQ_CD; + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < 2) { + int val = dma_channel_read(dev->DmaChannel); + buf[dev->dma_86c01.pos++] = val & 0xff; + } + dev->dma_86c01.pos = 0; + dma_set_drq(dev->DmaChannel, 0); + } else + esp_pci_dma_memory_rw(dev, buf, 2, WRITE_TO_DEVICE); + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; + dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; + dev->rregs[ESP_RSEQ] = SEQ_CD; } else { - fifo8_reset(&dev->fifo); - fifo8_push_all(&dev->fifo, buf, 2); - dev->rregs[ESP_RFLAGS] = 2; + fifo8_reset(&dev->fifo); + fifo8_push_all(&dev->fifo, buf, 2); + dev->rregs[ESP_RFLAGS] = 2; } esp_log("ESP SCSI ICCS IRQ\n"); esp_raise_irq(dev); @@ -957,234 +954,231 @@ esp_callback(void *p) esp_t *dev = (esp_t *) p; if (dev->dma_enabled || dev->do_cmd) { - if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_TI) { - esp_log("ESP SCSI Handle TI Callback\n"); - handle_ti(dev); - } + if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_TI) { + esp_log("ESP SCSI Handle TI Callback\n"); + handle_ti(dev); + } } - esp_log("ESP DMA activated = %d, CMD activated = %d\n", dev->dma_enabled, dev->do_cmd); + esp_log("ESP DMA activated = %d, CMD activated = %d\n", dev->dma_enabled, dev->do_cmd); } static uint32_t esp_reg_read(esp_t *dev, uint32_t saddr) { - uint32_t ret; + uint32_t ret; switch (saddr) { - case ESP_FIFO: - if ((dev->rregs[ESP_RSTAT] & 7) == STAT_DI) { - if (dev->ti_size) { - esp_log("TI size FIFO = %i\n", dev->ti_size); - esp_do_nodma(dev, &scsi_devices[dev->bus][dev->id]); - } else { - /* - * The last byte of a non-DMA transfer has been read out - * of the FIFO so switch to status phase - */ - dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; - } - } - - dev->rregs[ESP_FIFO] = esp_fifo_pop(&dev->fifo); - ret = dev->rregs[ESP_FIFO]; - break; - case ESP_RINTR: - /* Clear sequence step, interrupt register and all status bits - except TC */ - ret = dev->rregs[ESP_RINTR]; - dev->rregs[ESP_RINTR] = 0; - dev->rregs[ESP_RSTAT] &= ~STAT_TC; - esp_log("ESP SCSI Clear sequence step\n"); - esp_lower_irq(dev); - esp_log("ESP RINTR read old val = %02x\n", ret); - break; - case ESP_TCHI: - /* Return the unique id if the value has never been written */ - if (!dev->tchi_written && !dev->mca) { - esp_log("ESP TCHI read id 0x12\n"); - ret = TCHI_AM53C974; - } else - ret = dev->rregs[saddr]; - break; - case ESP_RFLAGS: - ret = fifo8_num_used(&dev->fifo); - break; - default: - ret = dev->rregs[saddr]; - break; + case ESP_FIFO: + if ((dev->rregs[ESP_RSTAT] & 7) == STAT_DI) { + if (dev->ti_size) { + esp_log("TI size FIFO = %i\n", dev->ti_size); + esp_do_nodma(dev, &scsi_devices[dev->bus][dev->id]); + } else { + /* + * The last byte of a non-DMA transfer has been read out + * of the FIFO so switch to status phase + */ + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; + } + } + dev->rregs[ESP_FIFO] = esp_fifo_pop(&dev->fifo); + ret = dev->rregs[ESP_FIFO]; + break; + case ESP_RINTR: + /* Clear sequence step, interrupt register and all status bits + except TC */ + ret = dev->rregs[ESP_RINTR]; + dev->rregs[ESP_RINTR] = 0; + dev->rregs[ESP_RSTAT] &= ~STAT_TC; + esp_log("ESP SCSI Clear sequence step\n"); + esp_lower_irq(dev); + esp_log("ESP RINTR read old val = %02x\n", ret); + break; + case ESP_TCHI: + /* Return the unique id if the value has never been written */ + if (!dev->tchi_written && !dev->mca) { + esp_log("ESP TCHI read id 0x12\n"); + ret = TCHI_AM53C974; + } else + ret = dev->rregs[saddr]; + break; + case ESP_RFLAGS: + ret = fifo8_num_used(&dev->fifo); + break; + default: + ret = dev->rregs[saddr]; + break; } esp_log("Read reg %02x = %02x\n", saddr, ret); return ret; } - static void esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) { esp_log("Write reg %02x = %02x\n", saddr, val); switch (saddr) { - case ESP_TCHI: - dev->tchi_written = 1; - /* fall through */ - case ESP_TCLO: - case ESP_TCMID: - esp_log("Transfer count regs %02x = %i\n", saddr, val); - dev->rregs[ESP_RSTAT] &= ~STAT_TC; - break; - case ESP_FIFO: - if (dev->do_cmd) { - esp_fifo_push(&dev->cmdfifo, val); - esp_log("ESP CmdVal = %02x\n", val); - /* - * If any unexpected message out/command phase data is - * transferred using non-DMA, raise the interrupt - */ - if (dev->rregs[ESP_CMD] == CMD_TI) { - dev->rregs[ESP_RINTR] |= INTR_BS; - esp_raise_irq(dev); + case ESP_TCHI: + dev->tchi_written = 1; + /* fall through */ + case ESP_TCLO: + case ESP_TCMID: + esp_log("Transfer count regs %02x = %i\n", saddr, val); + dev->rregs[ESP_RSTAT] &= ~STAT_TC; + break; + case ESP_FIFO: + if (dev->do_cmd) { + esp_fifo_push(&dev->cmdfifo, val); + esp_log("ESP CmdVal = %02x\n", val); + /* + * If any unexpected message out/command phase data is + * transferred using non-DMA, raise the interrupt + */ + if (dev->rregs[ESP_CMD] == CMD_TI) { + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } + } else { + esp_fifo_push(&dev->fifo, val); + esp_log("ESP fifoval = %02x\n", val); } - } else { - esp_fifo_push(&dev->fifo, val); - esp_log("ESP fifoval = %02x\n", val); - } - break; - case ESP_CMD: - dev->rregs[saddr] = val; + break; + case ESP_CMD: + dev->rregs[saddr] = val; - if (val & CMD_DMA) { - dev->dma = 1; - /* Reload DMA counter. */ - esp_set_tc(dev, esp_get_stc(dev)); - if (dev->mca) - esp_dma_enable(dev, 1); - } else { - dev->dma = 0; - esp_log("ESP Command not for DMA\n"); - if (dev->mca) - esp_dma_enable(dev, 0); - } - esp_log("[%04X:%08X]: ESP Command = %02x, DMA ena1 = %d, DMA ena2 = %d\n", CS, cpu_state.pc, val & (CMD_CMD|CMD_DMA), dev->dma, dev->dma_enabled); - switch (val & CMD_CMD) { - case CMD_NOP: - break; - case CMD_FLUSH: - fifo8_reset(&dev->fifo); - timer_on_auto(&dev->timer, 10.0); - break; - case CMD_RESET: - if (dev->mca) { - esp_lower_irq(dev); - esp_hard_reset(dev); - } else - esp_pci_soft_reset(dev); - break; - case CMD_BUSRESET: - if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { - dev->rregs[ESP_RINTR] |= INTR_RST; - esp_log("ESP Bus Reset with IRQ\n"); - esp_raise_irq(dev); - } - break; - case CMD_TI: - break; - case CMD_SEL: - handle_s_without_atn(dev); - break; - case CMD_SELATN: - handle_satn(dev); - break; - case CMD_SELATNS: - handle_satn_stop(dev); - break; - case CMD_ICCS: - esp_write_response(dev); - dev->rregs[ESP_RINTR] |= INTR_FC; - dev->rregs[ESP_RSTAT] |= STAT_MI; - break; - case CMD_MSGACC: - dev->rregs[ESP_RINTR] |= INTR_DC; - dev->rregs[ESP_RSEQ] = 0; - dev->rregs[ESP_RFLAGS] = 0; - esp_log("ESP SCSI MSGACC IRQ\n"); - esp_raise_irq(dev); - break; - case CMD_PAD: - dev->rregs[ESP_RSTAT] = STAT_TC; - dev->rregs[ESP_RINTR] |= INTR_FC; - dev->rregs[ESP_RSEQ] = 0; - esp_log("ESP Transfer Pad\n"); - break; - case CMD_SATN: - case CMD_RSTATN: - break; - case CMD_ENSEL: - dev->rregs[ESP_RINTR] = 0; - esp_log("ESP Enable Selection, do cmd = %d\n", dev->do_cmd); - break; - case CMD_DISSEL: - dev->rregs[ESP_RINTR] = 0; - esp_log("ESP Disable Selection\n"); - esp_raise_irq(dev); - break; - } - break; - case ESP_WBUSID: - case ESP_WSEL: - case ESP_WSYNTP: - case ESP_WSYNO: - break; - case ESP_CFG1: - case ESP_CFG2: - case ESP_CFG3: - case ESP_RES3: - case ESP_RES4: - dev->rregs[saddr] = val; - break; - case ESP_WCCF: - case ESP_WTEST: - break; - default: - esp_log("Unhandled writeb 0x%x = 0x%x\n", saddr, val); - break; + if (val & CMD_DMA) { + dev->dma = 1; + /* Reload DMA counter. */ + esp_set_tc(dev, esp_get_stc(dev)); + if (dev->mca) + esp_dma_enable(dev, 1); + } else { + dev->dma = 0; + esp_log("ESP Command not for DMA\n"); + if (dev->mca) + esp_dma_enable(dev, 0); + } + esp_log("[%04X:%08X]: ESP Command = %02x, DMA ena1 = %d, DMA ena2 = %d\n", CS, cpu_state.pc, val & (CMD_CMD | CMD_DMA), dev->dma, dev->dma_enabled); + switch (val & CMD_CMD) { + case CMD_NOP: + break; + case CMD_FLUSH: + fifo8_reset(&dev->fifo); + timer_on_auto(&dev->timer, 10.0); + break; + case CMD_RESET: + if (dev->mca) { + esp_lower_irq(dev); + esp_hard_reset(dev); + } else + esp_pci_soft_reset(dev); + break; + case CMD_BUSRESET: + if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { + dev->rregs[ESP_RINTR] |= INTR_RST; + esp_log("ESP Bus Reset with IRQ\n"); + esp_raise_irq(dev); + } + break; + case CMD_TI: + break; + case CMD_SEL: + handle_s_without_atn(dev); + break; + case CMD_SELATN: + handle_satn(dev); + break; + case CMD_SELATNS: + handle_satn_stop(dev); + break; + case CMD_ICCS: + esp_write_response(dev); + dev->rregs[ESP_RINTR] |= INTR_FC; + dev->rregs[ESP_RSTAT] |= STAT_MI; + break; + case CMD_MSGACC: + dev->rregs[ESP_RINTR] |= INTR_DC; + dev->rregs[ESP_RSEQ] = 0; + dev->rregs[ESP_RFLAGS] = 0; + esp_log("ESP SCSI MSGACC IRQ\n"); + esp_raise_irq(dev); + break; + case CMD_PAD: + dev->rregs[ESP_RSTAT] = STAT_TC; + dev->rregs[ESP_RINTR] |= INTR_FC; + dev->rregs[ESP_RSEQ] = 0; + esp_log("ESP Transfer Pad\n"); + break; + case CMD_SATN: + case CMD_RSTATN: + break; + case CMD_ENSEL: + dev->rregs[ESP_RINTR] = 0; + esp_log("ESP Enable Selection, do cmd = %d\n", dev->do_cmd); + break; + case CMD_DISSEL: + dev->rregs[ESP_RINTR] = 0; + esp_log("ESP Disable Selection\n"); + esp_raise_irq(dev); + break; + } + break; + case ESP_WBUSID: + case ESP_WSEL: + case ESP_WSYNTP: + case ESP_WSYNO: + break; + case ESP_CFG1: + case ESP_CFG2: + case ESP_CFG3: + case ESP_RES3: + case ESP_RES4: + dev->rregs[saddr] = val; + break; + case ESP_WCCF: + case ESP_WTEST: + break; + default: + esp_log("Unhandled writeb 0x%x = 0x%x\n", saddr, val); + break; } dev->wregs[saddr] = val; } - static void esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) { int expected_dir; - if (dev->dma_regs[DMA_CMD] & DMA_CMD_DIR) - expected_dir = READ_FROM_DEVICE; - else - expected_dir = WRITE_TO_DEVICE; + if (dev->dma_regs[DMA_CMD] & DMA_CMD_DIR) + expected_dir = READ_FROM_DEVICE; + else + expected_dir = WRITE_TO_DEVICE; - esp_log("ESP DMA WBC = %d, addr = %06x, expected direction = %d, dir = %i\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir, dir); + esp_log("ESP DMA WBC = %d, addr = %06x, expected direction = %d, dir = %i\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir, dir); - if (dir != expected_dir) { - esp_log("ESP unexpected direction\n"); - return; - } + if (dir != expected_dir) { + esp_log("ESP unexpected direction\n"); + return; + } - if (dev->dma_regs[DMA_WBC] < len) - len = dev->dma_regs[DMA_WBC]; + if (dev->dma_regs[DMA_WBC] < len) + len = dev->dma_regs[DMA_WBC]; - if (expected_dir) { - dma_bm_write(dev->dma_regs[DMA_SPA], buf, len, 4); - } else { - dma_bm_read(dev->dma_regs[DMA_SPA], buf, len, 4); - } + if (expected_dir) { + dma_bm_write(dev->dma_regs[DMA_SPA], buf, len, 4); + } else { + dma_bm_read(dev->dma_regs[DMA_SPA], buf, len, 4); + } - /* update status registers */ - dev->dma_regs[DMA_WBC] -= len; - dev->dma_regs[DMA_WAC] += len; - if (dev->dma_regs[DMA_WBC] == 0) - dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + /* update status registers */ + dev->dma_regs[DMA_WBC] -= len; + dev->dma_regs[DMA_WAC] += len; + if (dev->dma_regs[DMA_WBC] == 0) + dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; } static uint32_t @@ -1195,15 +1189,14 @@ esp_pci_dma_read(esp_t *dev, uint16_t saddr) ret = dev->dma_regs[saddr]; if (saddr == DMA_STAT) { - if (dev->rregs[ESP_RSTAT] & STAT_INT) { - ret |= DMA_STAT_SCSIINT; - esp_log("ESP PCI DMA Read SCSI interrupt issued\n"); - } + if (dev->rregs[ESP_RSTAT] & STAT_INT) { + ret |= DMA_STAT_SCSIINT; + esp_log("ESP PCI DMA Read SCSI interrupt issued\n"); + } if (!(dev->sbac & SBAC_STATUS)) { - dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_ERROR | DMA_STAT_ABORT | - DMA_STAT_DONE); - esp_log("ESP PCI DMA Read done cleared\n"); - } + dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE); + esp_log("ESP PCI DMA Read done cleared\n"); + } } esp_log("ESP PCI DMA Read regs addr = %04x, temp = %06x\n", saddr, ret); @@ -1216,43 +1209,41 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) uint32_t mask; switch (saddr) { - case DMA_CMD: - dev->dma_regs[saddr] = val; - esp_log("ESP PCI DMA Write CMD = %02x\n", val & DMA_CMD_MASK); - switch (val & DMA_CMD_MASK) { - case 0: /*IDLE*/ - esp_dma_enable(dev, 0); - break; - case 1: /*BLAST*/ - break; - case 2: /*ABORT*/ - scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]); - break; - case 3: /*START*/ - dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; - dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA]; - dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA]; - dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | - DMA_STAT_DONE | DMA_STAT_ABORT | - DMA_STAT_ERROR | DMA_STAT_PWDN); - esp_dma_enable(dev, 1); - break; - default: /* can't happen */ - abort(); - } - break; - case DMA_STC: - case DMA_SPA: - case DMA_SMDLA: - dev->dma_regs[saddr] = val; - break; - case DMA_STAT: - if (dev->sbac & SBAC_STATUS) { - /* clear some bits on write */ - mask = DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE; - dev->dma_regs[DMA_STAT] &= ~(val & mask); - } - break; + case DMA_CMD: + dev->dma_regs[saddr] = val; + esp_log("ESP PCI DMA Write CMD = %02x\n", val & DMA_CMD_MASK); + switch (val & DMA_CMD_MASK) { + case 0: /*IDLE*/ + esp_dma_enable(dev, 0); + break; + case 1: /*BLAST*/ + break; + case 2: /*ABORT*/ + scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]); + break; + case 3: /*START*/ + dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; + dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA]; + dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA]; + dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN); + esp_dma_enable(dev, 1); + break; + default: /* can't happen */ + abort(); + } + break; + case DMA_STC: + case DMA_SPA: + case DMA_SMDLA: + dev->dma_regs[saddr] = val; + break; + case DMA_STAT: + if (dev->sbac & SBAC_STATUS) { + /* clear some bits on write */ + mask = DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE; + dev->dma_regs[DMA_STAT] &= ~(val & mask); + } + break; } } @@ -1268,12 +1259,12 @@ esp_pci_hard_reset(esp_t *dev) { esp_hard_reset(dev); dev->dma_regs[DMA_CMD] &= ~(DMA_CMD_DIR | DMA_CMD_INTE_D | DMA_CMD_INTE_P - | DMA_CMD_MDL | DMA_CMD_DIAG | DMA_CMD_MASK); + | DMA_CMD_MDL | DMA_CMD_DIAG | DMA_CMD_MASK); dev->dma_regs[DMA_WBC] &= ~0xffff; dev->dma_regs[DMA_WAC] = 0xffffffff; dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT - | DMA_STAT_DONE | DMA_STAT_ABORT - | DMA_STAT_ERROR); + | DMA_STAT_DONE | DMA_STAT_ABORT + | DMA_STAT_ERROR); dev->dma_regs[DMA_WMAC] = 0xfffffffd; } @@ -1285,24 +1276,24 @@ esp_io_pci_read(esp_t *dev, uint32_t addr, unsigned int size) addr &= 0x7f; if (addr < 0x40) { - /* SCSI core reg */ - ret = esp_reg_read(dev, addr >> 2); + /* SCSI core reg */ + ret = esp_reg_read(dev, addr >> 2); } else if (addr < 0x60) { - /* PCI DMA CCB */ - ret = esp_pci_dma_read(dev, (addr - 0x40) >> 2); - esp_log("ESP PCI DMA CCB read addr = %02x, ret = %02x\n", (addr - 0x40) >> 2, ret); + /* PCI DMA CCB */ + ret = esp_pci_dma_read(dev, (addr - 0x40) >> 2); + esp_log("ESP PCI DMA CCB read addr = %02x, ret = %02x\n", (addr - 0x40) >> 2, ret); } else if (addr == 0x70) { - /* DMA SCSI Bus and control */ - ret = dev->sbac; - esp_log("ESP PCI SBAC read = %02x\n", ret); + /* DMA SCSI Bus and control */ + ret = dev->sbac; + esp_log("ESP PCI SBAC read = %02x\n", ret); } else { - /* Invalid region */ - ret = 0; + /* Invalid region */ + ret = 0; } /* give only requested data */ ret >>= (addr & 3) * 8; - ret &= ~(~(uint64_t)0 << (8 * size)); + ret &= ~(~(uint64_t) 0 << (8 * size)); esp_log("ESP PCI I/O read: addr = %02x, val = %02x\n", addr, ret); return ret; @@ -1312,7 +1303,7 @@ static void esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size) { uint32_t current, mask; - int shift; + int shift; addr &= 0x7f; @@ -1329,7 +1320,7 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size) } shift = (4 - size) * 8; - mask = (~(uint32_t)0 << shift) >> shift; + mask = (~(uint32_t) 0 << shift) >> shift; shift = ((4 - (addr & 3)) & 3) * 8; val <<= shift; @@ -1341,57 +1332,56 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size) esp_log("ESP PCI I/O write: addr = %02x, val = %02x\n", addr, val); if (addr < 0x40) { - /* SCSI core reg */ - esp_reg_write(dev, addr >> 2, val); + /* SCSI core reg */ + esp_reg_write(dev, addr >> 2, val); } else if (addr < 0x60) { - /* PCI DMA CCB */ - esp_pci_dma_write(dev, (addr - 0x40) >> 2, val); + /* PCI DMA CCB */ + esp_pci_dma_write(dev, (addr - 0x40) >> 2, val); } else if (addr == 0x70) { - /* DMA SCSI Bus and control */ - dev->sbac = val; + /* DMA SCSI Bus and control */ + dev->sbac = val; } } - static void esp_pci_io_writeb(uint16_t addr, uint8_t val, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; esp_io_pci_write(dev, addr, val, 1); } static void esp_pci_io_writew(uint16_t addr, uint16_t val, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; esp_io_pci_write(dev, addr, val, 2); } static void esp_pci_io_writel(uint16_t addr, uint32_t val, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; esp_io_pci_write(dev, addr, val, 4); } static uint8_t esp_pci_io_readb(uint16_t addr, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; return esp_io_pci_read(dev, addr, 1); } static uint16_t esp_pci_io_readw(uint16_t addr, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; return esp_io_pci_read(dev, addr, 2); } static uint32_t esp_pci_io_readl(uint16_t addr, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; return esp_io_pci_read(dev, addr, 4); } @@ -1400,18 +1390,17 @@ esp_io_set(esp_t *dev, uint32_t base, uint16_t len) { esp_log("ESP: [PCI] Setting I/O handler at %04X\n", base); io_sethandler(base, len, - esp_pci_io_readb, esp_pci_io_readw, esp_pci_io_readl, - esp_pci_io_writeb, esp_pci_io_writew, esp_pci_io_writel, dev); + esp_pci_io_readb, esp_pci_io_readw, esp_pci_io_readl, + esp_pci_io_writeb, esp_pci_io_writew, esp_pci_io_writel, dev); } - static void esp_io_remove(esp_t *dev, uint32_t base, uint16_t len) { esp_log("ESP: [PCI] Removing I/O handler at %04X\n", base); io_removehandler(base, len, - esp_pci_io_readb, esp_pci_io_readw, esp_pci_io_readl, - esp_pci_io_writeb, esp_pci_io_writew, esp_pci_io_writel, dev); + esp_pci_io_readb, esp_pci_io_readw, esp_pci_io_readl, + esp_pci_io_writeb, esp_pci_io_writew, esp_pci_io_writel, dev); } static void @@ -1426,15 +1415,15 @@ esp_bios_disable(esp_t *dev) mem_mapping_disable(&dev->bios.mapping); } -#define EE_ADAPT_SCSI_ID 64 -#define EE_MODE2 65 -#define EE_DELAY 66 -#define EE_TAG_CMD_NUM 67 -#define EE_ADAPT_OPTIONS 68 -#define EE_BOOT_SCSI_ID 69 -#define EE_BOOT_SCSI_LUN 70 -#define EE_CHKSUM1 126 -#define EE_CHKSUM2 127 +#define EE_ADAPT_SCSI_ID 64 +#define EE_MODE2 65 +#define EE_DELAY 66 +#define EE_TAG_CMD_NUM 67 +#define EE_ADAPT_OPTIONS 68 +#define EE_BOOT_SCSI_ID 69 +#define EE_BOOT_SCSI_LUN 70 +#define EE_CHKSUM1 126 +#define EE_CHKSUM2 127 #define EE_ADAPT_OPTION_F6_F8_AT_BOOT 0x01 #define EE_ADAPT_OPTION_BOOT_FROM_CDROM 0x02 @@ -1445,334 +1434,337 @@ esp_bios_disable(esp_t *dev) static void dc390_save_eeprom(esp_t *dev) { - FILE *f = nvr_fopen(dev->nvr_path, "wb"); - if (!f) return; - fwrite(dev->eeprom.data, 1, 128, f); - fclose(f); + FILE *f = nvr_fopen(dev->nvr_path, "wb"); + if (!f) + return; + fwrite(dev->eeprom.data, 1, 128, f); + fclose(f); } static void dc390_write_eeprom(esp_t *dev, int ena, int clk, int dat) { - /*Actual EEPROM is the same as the one used by the ATI cards, the 93cxx series.*/ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t tick = eeprom->count; - uint8_t eedo = eeprom->out; - uint16_t address = eeprom->address; - uint8_t command = eeprom->opcode; + /*Actual EEPROM is the same as the one used by the ATI cards, the 93cxx series.*/ + ati_eeprom_t *eeprom = &dev->eeprom; + uint8_t tick = eeprom->count; + uint8_t eedo = eeprom->out; + uint16_t address = eeprom->address; + uint8_t command = eeprom->opcode; - esp_log("EEPROM CS=%02x,SK=%02x,DI=%02x,DO=%02x,tick=%d\n", - ena, clk, dat, eedo, tick); + esp_log("EEPROM CS=%02x,SK=%02x,DI=%02x,DO=%02x,tick=%d\n", + ena, clk, dat, eedo, tick); - if (!eeprom->oldena && ena) { - esp_log("EEPROM Start chip select cycle\n"); - tick = 0; - command = 0; - address = 0; - } else if (eeprom->oldena && !ena) { - if (!eeprom->wp) { - uint8_t subcommand = address >> 4; - if (command == 0 && subcommand == 2) { - esp_log("EEPROM Erase All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (command == 3) { - esp_log("EEPROM Erase Word\n"); - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (tick >= 26) { - if (command == 1) { - esp_log("EEPROM Write Word\n"); - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } else if (command == 0 && subcommand == 1) { - esp_log("EEPROM Write All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } - } - } - eedo = 1; - esp_log("EEPROM DO read\n"); - } else if (ena && !eeprom->oldclk && clk) { - if (tick == 0) { - if (dat == 0) { - esp_log("EEPROM Got correct 1st start bit, waiting for 2nd start bit (1)\n"); - tick++; - } else { - esp_log("EEPROM Wrong 1st start bit (is 1, should be 0)\n"); - tick = 2; - } - } else if (tick == 1) { - if (dat != 0) { - esp_log("EEPROM Got correct 2nd start bit, getting command + address\n"); - tick++; - } else { - esp_log("EEPROM 1st start bit is longer than needed\n"); - } - } else if (tick < 4) { - tick++; - command <<= 1; - if (dat) - command += 1; - } else if (tick < 10) { - tick++; - address = (address << 1) | dat; - if (tick == 10) { - esp_log("EEPROM command = %02x, address = %02x (val = %04x)\n", command, - address, eeprom->data[address]); - if (command == 2) - eedo = 0; - address = address % 64; - if (command == 0) { - switch (address >> 4) { - case 0: - esp_log("EEPROM Write disable command\n"); - eeprom->wp = 1; - break; - case 1: - esp_log("EEPROM Write all command\n"); - break; - case 2: - esp_log("EEPROM Erase all command\n"); - break; - case 3: - esp_log("EEPROM Write enable command\n"); - eeprom->wp = 0; - break; - } - } else { - esp_log("EEPROM Read, write or erase word\n"); - eeprom->dat = eeprom->data[address]; - } - } - } else if (tick < 26) { - tick++; - if (command == 2) { - esp_log("EEPROM Read Word\n"); - eedo = ((eeprom->dat & 0x8000) != 0); - } - eeprom->dat <<= 1; - eeprom->dat += dat; - } else { - esp_log("EEPROM Additional unneeded tick, not processed\n"); - } - } + if (!eeprom->oldena && ena) { + esp_log("EEPROM Start chip select cycle\n"); + tick = 0; + command = 0; + address = 0; + } else if (eeprom->oldena && !ena) { + if (!eeprom->wp) { + uint8_t subcommand = address >> 4; + if (command == 0 && subcommand == 2) { + esp_log("EEPROM Erase All\n"); + for (address = 0; address < 64; address++) + eeprom->data[address] = 0xffff; + dc390_save_eeprom(dev); + } else if (command == 3) { + esp_log("EEPROM Erase Word\n"); + eeprom->data[address] = 0xffff; + dc390_save_eeprom(dev); + } else if (tick >= 26) { + if (command == 1) { + esp_log("EEPROM Write Word\n"); + eeprom->data[address] &= eeprom->dat; + dc390_save_eeprom(dev); + } else if (command == 0 && subcommand == 1) { + esp_log("EEPROM Write All\n"); + for (address = 0; address < 64; address++) + eeprom->data[address] &= eeprom->dat; + dc390_save_eeprom(dev); + } + } + } + eedo = 1; + esp_log("EEPROM DO read\n"); + } else if (ena && !eeprom->oldclk && clk) { + if (tick == 0) { + if (dat == 0) { + esp_log("EEPROM Got correct 1st start bit, waiting for 2nd start bit (1)\n"); + tick++; + } else { + esp_log("EEPROM Wrong 1st start bit (is 1, should be 0)\n"); + tick = 2; + } + } else if (tick == 1) { + if (dat != 0) { + esp_log("EEPROM Got correct 2nd start bit, getting command + address\n"); + tick++; + } else { + esp_log("EEPROM 1st start bit is longer than needed\n"); + } + } else if (tick < 4) { + tick++; + command <<= 1; + if (dat) + command += 1; + } else if (tick < 10) { + tick++; + address = (address << 1) | dat; + if (tick == 10) { + esp_log("EEPROM command = %02x, address = %02x (val = %04x)\n", command, + address, eeprom->data[address]); + if (command == 2) + eedo = 0; + address = address % 64; + if (command == 0) { + switch (address >> 4) { + case 0: + esp_log("EEPROM Write disable command\n"); + eeprom->wp = 1; + break; + case 1: + esp_log("EEPROM Write all command\n"); + break; + case 2: + esp_log("EEPROM Erase all command\n"); + break; + case 3: + esp_log("EEPROM Write enable command\n"); + eeprom->wp = 0; + break; + } + } else { + esp_log("EEPROM Read, write or erase word\n"); + eeprom->dat = eeprom->data[address]; + } + } + } else if (tick < 26) { + tick++; + if (command == 2) { + esp_log("EEPROM Read Word\n"); + eedo = ((eeprom->dat & 0x8000) != 0); + } + eeprom->dat <<= 1; + eeprom->dat += dat; + } else { + esp_log("EEPROM Additional unneeded tick, not processed\n"); + } + } - eeprom->count = tick; - eeprom->oldena = ena; - eeprom->oldclk = clk; - eeprom->out = eedo; - eeprom->address = address; - eeprom->opcode = command; - esp_log("EEPROM EEDO = %d\n", eeprom->out); + eeprom->count = tick; + eeprom->oldena = ena; + eeprom->oldclk = clk; + eeprom->out = eedo; + eeprom->address = address; + eeprom->opcode = command; + esp_log("EEPROM EEDO = %d\n", eeprom->out); } static void dc390_load_eeprom(esp_t *dev) { ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t *nvr = (uint8_t *)eeprom->data; - int i; - uint16_t checksum = 0; - FILE *f; + uint8_t *nvr = (uint8_t *) eeprom->data; + int i; + uint16_t checksum = 0; + FILE *f; eeprom->out = 1; f = nvr_fopen(dev->nvr_path, "rb"); if (f) { - esp_log("EEPROM Load\n"); - if (fread(nvr, 1, 128, f) != 128) - fatal("dc390_eeprom_load(): Error reading data\n"); - fclose(f); + esp_log("EEPROM Load\n"); + if (fread(nvr, 1, 128, f) != 128) + fatal("dc390_eeprom_load(): Error reading data\n"); + fclose(f); } else { - for (i = 0; i < 16; i++) { - nvr[i * 2] = 0x57; - nvr[i * 2 + 1] = 0x00; - } + for (i = 0; i < 16; i++) { + nvr[i * 2] = 0x57; + nvr[i * 2 + 1] = 0x00; + } - esp_log("EEPROM Defaults\n"); + esp_log("EEPROM Defaults\n"); - nvr[EE_ADAPT_SCSI_ID] = 7; - nvr[EE_MODE2] = 0x0f; - nvr[EE_TAG_CMD_NUM] = 0x04; - nvr[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | - EE_ADAPT_OPTION_BOOT_FROM_CDROM | - EE_ADAPT_OPTION_INT13; - for (i = 0; i < EE_CHKSUM1; i += 2) { - checksum += ((nvr[i] & 0xff) | (nvr[i + 1] << 8)); - esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, nvr[i]); - } + nvr[EE_ADAPT_SCSI_ID] = 7; + nvr[EE_MODE2] = 0x0f; + nvr[EE_TAG_CMD_NUM] = 0x04; + nvr[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; + for (i = 0; i < EE_CHKSUM1; i += 2) { + checksum += ((nvr[i] & 0xff) | (nvr[i + 1] << 8)); + esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, nvr[i]); + } - checksum = 0x1234 - checksum; - nvr[EE_CHKSUM1] = checksum & 0xff; - nvr[EE_CHKSUM2] = checksum >> 8; - esp_log("EEPROM Checksum = %04x\n", checksum); + checksum = 0x1234 - checksum; + nvr[EE_CHKSUM1] = checksum & 0xff; + nvr[EE_CHKSUM2] = checksum >> 8; + esp_log("EEPROM Checksum = %04x\n", checksum); } } -uint8_t esp_pci_regs[256]; -bar_t esp_pci_bar[2]; - +uint8_t esp_pci_regs[256]; +bar_t esp_pci_bar[2]; static uint8_t esp_pci_read(int func, int addr, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; - //esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); + // esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); switch (addr) { - case 0x00: - //esp_log("ESP PCI: Read DO line = %02x\n", dev->eeprom.out); - if (!dev->has_bios) - return 0x22; - else { - if (dev->eeprom.out) - return 0x22; - else { - dev->eeprom.out = 1; - return 2; - } - } - break; - case 0x01: - return 0x10; - case 0x02: - return 0x20; - case 0x03: - return 0x20; - case 0x04: - return esp_pci_regs[0x04] & 3; /*Respond to IO*/ - case 0x07: - return 2; - case 0x08: - return 0; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - case 0x0A: - return 0; /*devubclass*/ - case 0x0B: - return 1; /*Class code*/ - case 0x0E: - return 0; /*Header type */ - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return esp_pci_bar[0].addr_regs[1]; - case 0x12: - return esp_pci_bar[0].addr_regs[2]; - case 0x13: - return esp_pci_bar[0].addr_regs[3]; - case 0x30: - if (!dev->has_bios) - return 0; - return esp_pci_bar[1].addr_regs[0]; - case 0x31: - if (!dev->has_bios) - return 0; - return esp_pci_bar[1].addr_regs[1]; - case 0x32: - if (!dev->has_bios) - return 0; - return esp_pci_bar[1].addr_regs[2]; - case 0x33: - if (!dev->has_bios) - return 0; - return esp_pci_bar[1].addr_regs[3]; - case 0x3C: - return dev->irq; - case 0x3D: - return PCI_INTA; + case 0x00: + // esp_log("ESP PCI: Read DO line = %02x\n", dev->eeprom.out); + if (!dev->has_bios) + return 0x22; + else { + if (dev->eeprom.out) + return 0x22; + else { + dev->eeprom.out = 1; + return 2; + } + } + break; + case 0x01: + return 0x10; + case 0x02: + return 0x20; + case 0x03: + return 0x20; + case 0x04: + return esp_pci_regs[0x04] & 3; /*Respond to IO*/ + case 0x07: + return 2; + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0A: + return 0; /*devubclass*/ + case 0x0B: + return 1; /*Class code*/ + case 0x0E: + return 0; /*Header type */ + case 0x10: + return 1; /*I/O space*/ + case 0x11: + return esp_pci_bar[0].addr_regs[1]; + case 0x12: + return esp_pci_bar[0].addr_regs[2]; + case 0x13: + return esp_pci_bar[0].addr_regs[3]; + case 0x30: + if (!dev->has_bios) + return 0; + return esp_pci_bar[1].addr_regs[0]; + case 0x31: + if (!dev->has_bios) + return 0; + return esp_pci_bar[1].addr_regs[1]; + case 0x32: + if (!dev->has_bios) + return 0; + return esp_pci_bar[1].addr_regs[2]; + case 0x33: + if (!dev->has_bios) + return 0; + return esp_pci_bar[1].addr_regs[3]; + case 0x3C: + return dev->irq; + case 0x3D: + return PCI_INTA; - case 0x40 ... 0x4f: - return esp_pci_regs[addr]; + case 0x40 ... 0x4f: + return esp_pci_regs[addr]; } - return(0); + return (0); } - static void esp_pci_write(int func, int addr, uint8_t val, void *p) { - esp_t *dev = (esp_t *)p; + esp_t *dev = (esp_t *) p; uint8_t valxor; - int eesk; - int eedi; + int eesk; + int eedi; - //esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); + // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); if ((addr >= 0x80) && (addr <= 0xFF)) { - if (addr == 0x80) { - eesk = val & 0x80 ? 1 : 0; - eedi = val & 0x40 ? 1 : 0; - dc390_write_eeprom(dev, 1, eesk, eedi); - } else if (addr == 0xc0) - dc390_write_eeprom(dev, 0, 0, 0); - //esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); - return; + if (addr == 0x80) { + eesk = val & 0x80 ? 1 : 0; + eedi = val & 0x40 ? 1 : 0; + dc390_write_eeprom(dev, 1, eesk, eedi); + } else if (addr == 0xc0) + dc390_write_eeprom(dev, 0, 0, 0); + // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); + return; } switch (addr) { - case 0x04: - valxor = (val & 3) ^ esp_pci_regs[addr]; - if (valxor & PCI_COMMAND_IO) { - esp_io_remove(dev, dev->PCIBase, 0x80); - if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) - esp_io_set(dev, dev->PCIBase, 0x80); - } - esp_pci_regs[addr] = val & 3; - break; + case 0x04: + valxor = (val & 3) ^ esp_pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) { + esp_io_remove(dev, dev->PCIBase, 0x80); + if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) + esp_io_set(dev, dev->PCIBase, 0x80); + } + esp_pci_regs[addr] = val & 3; + break; - case 0x10: case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O. */ - esp_io_remove(dev, dev->PCIBase, 0x80); - /* Then let's set the PCI regs. */ - esp_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - esp_pci_bar[0].addr &= 0xff00; - dev->PCIBase = esp_pci_bar[0].addr; - /* Log the new base. */ - //esp_log("ESP PCI: New I/O base is %04X\n" , dev->PCIBase); - /* We're done, so get out of the here. */ - if (esp_pci_regs[4] & PCI_COMMAND_IO) { - if (dev->PCIBase != 0) { - esp_io_set(dev, dev->PCIBase, 0x80); - } - } - return; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O. */ + esp_io_remove(dev, dev->PCIBase, 0x80); + /* Then let's set the PCI regs. */ + esp_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + esp_pci_bar[0].addr &= 0xff00; + dev->PCIBase = esp_pci_bar[0].addr; + /* Log the new base. */ + // esp_log("ESP PCI: New I/O base is %04X\n" , dev->PCIBase); + /* We're done, so get out of the here. */ + if (esp_pci_regs[4] & PCI_COMMAND_IO) { + if (dev->PCIBase != 0) { + esp_io_set(dev, dev->PCIBase, 0x80); + } + } + return; - case 0x30: case 0x31: case 0x32: case 0x33: - if (!dev->has_bios) - return; - /* BIOS Base set. */ - /* First, remove the old I/O. */ - esp_bios_disable(dev); - /* Then let's set the PCI regs. */ - esp_pci_bar[1].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - esp_pci_bar[1].addr &= 0xfff80001; - dev->BIOSBase = esp_pci_bar[1].addr & 0xfff80000; - /* Log the new base. */ - //esp_log("ESP PCI: New BIOS base is %08X\n" , dev->BIOSBase); - /* We're done, so get out of the here. */ - if (esp_pci_bar[1].addr & 0x00000001) - esp_bios_set_addr(dev, dev->BIOSBase); - return; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + if (!dev->has_bios) + return; + /* BIOS Base set. */ + /* First, remove the old I/O. */ + esp_bios_disable(dev); + /* Then let's set the PCI regs. */ + esp_pci_bar[1].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + esp_pci_bar[1].addr &= 0xfff80001; + dev->BIOSBase = esp_pci_bar[1].addr & 0xfff80000; + /* Log the new base. */ + // esp_log("ESP PCI: New BIOS base is %08X\n" , dev->BIOSBase); + /* We're done, so get out of the here. */ + if (esp_pci_bar[1].addr & 0x00000001) + esp_bios_set_addr(dev, dev->BIOSBase); + return; - case 0x3C: - esp_pci_regs[addr] = val; - dev->irq = val; - esp_log("ESP IRQ now: %i\n", val); - return; + case 0x3C: + esp_pci_regs[addr] = val; + dev->irq = val; + esp_log("ESP IRQ now: %i\n", val); + return; - case 0x40 ... 0x4f: - esp_pci_regs[addr] = val; - return; + case 0x40 ... 0x4f: + esp_pci_regs[addr] = val; + return; } } @@ -1786,152 +1778,152 @@ dc390_init(const device_t *info) dev->bus = scsi_get_bus(); - dev->mca = 0; + dev->mca = 0; fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->PCIBase = 0; + dev->PCIBase = 0; dev->MMIOBase = 0; dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev); esp_pci_bar[0].addr_regs[0] = 1; - esp_pci_regs[0x04] = 3; + esp_pci_regs[0x04] = 3; dev->has_bios = device_get_config_int("bios"); if (dev->has_bios) - rom_init(&dev->bios, DC390_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&dev->bios, DC390_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); /* Enable our BIOS space in PCI, if needed. */ if (dev->has_bios) { - esp_pci_bar[1].addr = 0xfff80000; + esp_pci_bar[1].addr = 0xfff80000; } else { - esp_pci_bar[1].addr = 0; + esp_pci_bar[1].addr = 0; } if (dev->has_bios) - esp_bios_disable(dev); + esp_bios_disable(dev); - dev->nvr_path = "dc390.nvr"; + dev->nvr_path = "dc390.nvr"; - /* Load the serial EEPROM. */ - dc390_load_eeprom(dev); + /* Load the serial EEPROM. */ + dc390_load_eeprom(dev); esp_pci_hard_reset(dev); timer_add(&dev->timer, esp_callback, dev, 0); - return(dev); + return (dev); } static uint16_t ncr53c90_in(uint16_t port, void *priv) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; uint16_t ret = 0; - port &= 0x1f; + port &= 0x1f; - if (port >= 0x10) - ret = esp_reg_read(dev, port - 0x10); - else { - switch (port) { - case 0x02: - ret = dev->dma_86c01.mode; - break; + if (port >= 0x10) + ret = esp_reg_read(dev, port - 0x10); + else { + switch (port) { + case 0x02: + ret = dev->dma_86c01.mode; + break; - case 0x0c: - ret = dev->dma_86c01.status; - break; - } - } + case 0x0c: + ret = dev->dma_86c01.status; + break; + } + } - esp_log("[%04X:%08X]: NCR53c90 DMA read port = %02x, ret = %02x\n", CS, cpu_state.pc, port, ret); + esp_log("[%04X:%08X]: NCR53c90 DMA read port = %02x, ret = %02x\n", CS, cpu_state.pc, port, ret); - return ret; + return ret; } static uint8_t ncr53c90_inb(uint16_t port, void *priv) { - return ncr53c90_in(port, priv); + return ncr53c90_in(port, priv); } static uint16_t ncr53c90_inw(uint16_t port, void *priv) { - return (ncr53c90_in(port, priv) & 0xff) | (ncr53c90_in(port + 1, priv) << 8); + return (ncr53c90_in(port, priv) & 0xff) | (ncr53c90_in(port + 1, priv) << 8); } static void ncr53c90_out(uint16_t port, uint16_t val, void *priv) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; - port &= 0x1f; + port &= 0x1f; - esp_log("[%04X:%08X]: NCR53c90 DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); + esp_log("[%04X:%08X]: NCR53c90 DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); - if (port >= 0x10) - esp_reg_write(dev, port - 0x10, val); - else { - if (port == 0x02) { - dev->dma_86c01.mode = (val & 0x40); - } - } + if (port >= 0x10) + esp_reg_write(dev, port - 0x10, val); + else { + if (port == 0x02) { + dev->dma_86c01.mode = (val & 0x40); + } + } } static void ncr53c90_outb(uint16_t port, uint8_t val, void *priv) { - ncr53c90_out(port, val, priv); + ncr53c90_out(port, val, priv); } static void ncr53c90_outw(uint16_t port, uint16_t val, void *priv) { - ncr53c90_out(port, val & 0xff, priv); - ncr53c90_out(port + 1, val >> 8, priv); + ncr53c90_out(port, val & 0xff, priv); + ncr53c90_out(port + 1, val >> 8, priv); } static uint8_t ncr53c90_mca_read(int port, void *priv) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; - return(dev->pos_regs[port & 7]); + return (dev->pos_regs[port & 7]); } - static void ncr53c90_mca_write(int port, uint8_t val, void *priv) { - esp_t *dev = (esp_t *)priv; - static const uint16_t ncrmca_iobase[] = { - 0, 0x240, 0x340, 0x400, 0x420, 0x3240, 0x8240, 0xa240 - }; + esp_t *dev = (esp_t *) priv; + static const uint16_t ncrmca_iobase[] = { + 0, 0x240, 0x340, 0x400, 0x420, 0x3240, 0x8240, 0xa240 + }; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; /* Save the MCA register value. */ dev->pos_regs[port & 7] = val; /* This is always necessary so that the old handler doesn't remain. */ - if (dev->Base != 0) { - io_removehandler(dev->Base, 0x20, - ncr53c90_inb, ncr53c90_inw, NULL, - ncr53c90_outb, ncr53c90_outw, NULL, dev); - } + if (dev->Base != 0) { + io_removehandler(dev->Base, 0x20, + ncr53c90_inb, ncr53c90_inw, NULL, + ncr53c90_outb, ncr53c90_outw, NULL, dev); + } /* Get the new assigned I/O base address. */ dev->Base = ncrmca_iobase[(dev->pos_regs[2] & 0x0e) >> 1]; /* Save the new IRQ and DMA channel values. */ dev->irq = 3 + (2 * ((dev->pos_regs[2] & 0x30) >> 4)); - if (dev->irq == 9) - dev->irq = 2; + if (dev->irq == 9) + dev->irq = 2; dev->DmaChannel = dev->pos_regs[3] & 0x0f; @@ -1943,31 +1935,29 @@ ncr53c90_mca_write(int port, uint8_t val, void *priv) /* Initialize the device if fully configured. */ if (dev->pos_regs[2] & 0x01) { - if (dev->Base != 0) { - /* Card enabled; register (new) I/O handler. */ - io_sethandler(dev->Base, 0x20, - ncr53c90_inb, ncr53c90_inw, NULL, - ncr53c90_outb, ncr53c90_outw, NULL, dev); + if (dev->Base != 0) { + /* Card enabled; register (new) I/O handler. */ + io_sethandler(dev->Base, 0x20, + ncr53c90_inb, ncr53c90_inw, NULL, + ncr53c90_outb, ncr53c90_outw, NULL, dev); - esp_hard_reset(dev); - } + esp_hard_reset(dev); + } - /* Say hello. */ - esp_log("NCR 53c90: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", - dev->Base, dev->irq, dev->DmaChannel, dev->HostID); + /* Say hello. */ + esp_log("NCR 53c90: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", + dev->Base, dev->irq, dev->DmaChannel, dev->HostID); } } - static uint8_t ncr53c90_mca_feedb(void *priv) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; return (dev->pos_regs[2] & 0x01); } - static void * ncr53c90_mca_init(const device_t *info) { @@ -1978,39 +1968,38 @@ ncr53c90_mca_init(const device_t *info) dev->bus = scsi_get_bus(); - dev->mca = 1; + dev->mca = 1; fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4d; /* MCA board ID */ - dev->pos_regs[1] = 0x7f; - mca_add(ncr53c90_mca_read, ncr53c90_mca_write, ncr53c90_mca_feedb, NULL, dev); + dev->pos_regs[0] = 0x4d; /* MCA board ID */ + dev->pos_regs[1] = 0x7f; + mca_add(ncr53c90_mca_read, ncr53c90_mca_write, ncr53c90_mca_feedb, NULL, dev); esp_hard_reset(dev); timer_add(&dev->timer, esp_callback, dev, 0); - return(dev); + return (dev); } static void esp_close(void *priv) { - esp_t *dev = (esp_t *)priv; + esp_t *dev = (esp_t *) priv; if (dev) { - fifo8_destroy(&dev->fifo); - fifo8_destroy(&dev->cmdfifo); + fifo8_destroy(&dev->fifo); + fifo8_destroy(&dev->cmdfifo); - free(dev); - dev = NULL; + free(dev); + dev = NULL; } } - static const device_config_t bios_enable_config[] = { -// clang-format off + // clang-format off { .name = "bios", .description = "Enable BIOS", @@ -2023,29 +2012,29 @@ static const device_config_t bios_enable_config[] = { }; const device_t dc390_pci_device = { - .name = "Tekram DC-390 PCI", + .name = "Tekram DC-390 PCI", .internal_name = "dc390", - .flags = DEVICE_PCI, - .local = 0, - .init = dc390_init, - .close = esp_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = dc390_init, + .close = esp_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = bios_enable_config + .force_redraw = NULL, + .config = bios_enable_config }; const device_t ncr53c90_mca_device = { - .name = "NCR 53c90 MCA", + .name = "NCR 53c90 MCA", .internal_name = "ncr53c90", - .flags = DEVICE_MCA, - .local = 0, - .init = ncr53c90_mca_init, - .close = esp_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 0, + .init = ncr53c90_mca_init, + .close = esp_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index cfcf8e816..799be48d0 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -40,161 +40,160 @@ #include <86box/scsi_device.h> #include <86box/scsi_spock.h> -#define SPOCK_U68_1990_ROM "roms/scsi/ibm/64f4376.bin" -#define SPOCK_U69_1990_ROM "roms/scsi/ibm/64f4377.bin" +#define SPOCK_U68_1990_ROM "roms/scsi/ibm/64f4376.bin" +#define SPOCK_U69_1990_ROM "roms/scsi/ibm/64f4377.bin" -#define SPOCK_U68_1991_ROM "roms/scsi/ibm/92F2244.U68" -#define SPOCK_U69_1991_ROM "roms/scsi/ibm/92F2245.U69" +#define SPOCK_U68_1991_ROM "roms/scsi/ibm/92F2244.U68" +#define SPOCK_U69_1991_ROM "roms/scsi/ibm/92F2245.U69" -#define SPOCK_TIME (20) +#define SPOCK_TIME (20) -typedef enum -{ - SCSI_STATE_IDLE, - SCSI_STATE_SELECT, - SCSI_STATE_SEND_COMMAND, - SCSI_STATE_END_PHASE +typedef enum { + SCSI_STATE_IDLE, + SCSI_STATE_SELECT, + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_END_PHASE } scsi_state_t; -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint16_t pos; - uint16_t pos1; - uint16_t pos2; - uint16_t pos3; - uint16_t pos4; - uint16_t pos5; - uint16_t pos6; - uint16_t pos7; - uint16_t pos8; + uint16_t pos; + uint16_t pos1; + uint16_t pos2; + uint16_t pos3; + uint16_t pos4; + uint16_t pos5; + uint16_t pos6; + uint16_t pos7; + uint16_t pos8; } get_pos_info_t; typedef struct { - uint16_t scb_status; - uint16_t retry_count; - uint32_t residual_byte_count; - uint32_t sg_list_element_addr; - uint16_t device_dep_status_len; - uint16_t cmd_status; - uint16_t error; - uint16_t reserved; - uint16_t cache_info_status; - uint32_t scb_addr; + uint16_t scb_status; + uint16_t retry_count; + uint32_t residual_byte_count; + uint32_t sg_list_element_addr; + uint16_t device_dep_status_len; + uint16_t cmd_status; + uint16_t error; + uint16_t reserved; + uint16_t cache_info_status; + uint32_t scb_addr; } get_complete_stat_t; typedef struct { - uint32_t sys_buf_addr; - uint32_t sys_buf_byte_count; + uint32_t sys_buf_addr; + uint32_t sys_buf_byte_count; } SGE; typedef struct { - uint16_t command; - uint16_t enable; - uint32_t lba_addr; - SGE sge; - uint32_t term_status_block_addr; - uint32_t scb_chain_addr; - uint16_t block_count; - uint16_t block_length; + uint16_t command; + uint16_t enable; + uint32_t lba_addr; + SGE sge; + uint32_t term_status_block_addr; + uint32_t scb_chain_addr; + uint16_t block_count; + uint16_t block_length; } scb_t; #pragma pack(pop) typedef struct { - rom_t bios_rom; + rom_t bios_rom; - int bios_ver; - int irq, irq_inactive; + int bios_ver; + int irq, irq_inactive; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; - uint8_t basic_ctrl; - uint32_t command; + uint8_t basic_ctrl; + uint32_t command; - uint8_t attention, - attention_pending; - int attention_wait; + uint8_t attention, + attention_pending; + int attention_wait; - uint8_t cir[4], - cir_pending[4]; + uint8_t cir[4], + cir_pending[4]; - uint8_t irq_status; + uint8_t irq_status; - uint32_t scb_addr; + uint32_t scb_addr; - uint8_t status; + uint8_t status; - get_complete_stat_t get_complete_stat; - get_pos_info_t get_pos_info; + get_complete_stat_t get_complete_stat; + get_pos_info_t get_pos_info; - scb_t scb; - int adapter_reset; - int scb_id; - int adapter_id; + scb_t scb; + int adapter_reset; + int scb_id; + int adapter_id; - int cmd_status; - int cir_status; + int cmd_status; + int cir_status; - uint8_t pacing; + uint8_t pacing; - uint8_t buf[0x600]; + uint8_t buf[0x600]; - struct { - int phys_id; - int lun_id; - } dev_id[SCSI_ID_MAX]; + struct { + int phys_id; + int lun_id; + } dev_id[SCSI_ID_MAX]; - uint8_t last_status, bus; - uint8_t cdb[12]; - int cdb_len; - int cdb_id; - uint32_t data_ptr, data_len; - uint8_t temp_cdb[12]; + uint8_t last_status, bus; + uint8_t cdb[12]; + int cdb_len; + int cdb_id; + uint32_t data_ptr, data_len; + uint8_t temp_cdb[12]; - int irq_requests[SCSI_ID_MAX]; + int irq_requests[SCSI_ID_MAX]; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - int cmd_timer; + int cmd_timer; - int scb_state; - int in_reset; - int in_invalid; + int scb_state; + int in_reset; + int in_invalid; - uint64_t temp_period; - double media_period; + uint64_t temp_period; + double media_period; - scsi_state_t scsi_state; + scsi_state_t scsi_state; } spock_t; -#define CTRL_RESET (1 << 7) -#define CTRL_DMA_ENA (1 << 1) -#define CTRL_IRQ_ENA (1 << 0) +#define CTRL_RESET (1 << 7) +#define CTRL_DMA_ENA (1 << 1) +#define CTRL_IRQ_ENA (1 << 0) -#define STATUS_CMD_FULL (1 << 3) -#define STATUS_CMD_EMPTY (1 << 2) -#define STATUS_IRQ (1 << 1) -#define STATUS_BUSY (1 << 0) +#define STATUS_CMD_FULL (1 << 3) +#define STATUS_CMD_EMPTY (1 << 2) +#define STATUS_IRQ (1 << 1) +#define STATUS_BUSY (1 << 0) -#define ENABLE_PT (1 << 12) +#define ENABLE_PT (1 << 12) -#define CMD_MASK 0xff3f -#define CMD_ASSIGN 0x040e -#define CMD_DEVICE_INQUIRY 0x1c0b -#define CMD_DMA_PACING_CONTROL 0x040d -#define CMD_FEATURE_CONTROL 0x040c -#define CMD_GET_POS_INFO 0x1c0a -#define CMD_INVALID_412 0x0412 -#define CMD_GET_COMPLETE_STATUS 0x1c07 -#define CMD_FORMAT_UNIT 0x1c16 -#define CMD_READ_DATA 0x1c01 -#define CMD_READ_DEVICE_CAPACITY 0x1c09 -#define CMD_REQUEST_SENSE 0x1c08 -#define CMD_RESET 0x0400 -#define CMD_SEND_OTHER_SCSI 0x241f -#define CMD_UNKNOWN_1C10 0x1c10 -#define CMD_UNKNOWN_1C11 0x1c11 -#define CMD_WRITE_DATA 0x1c02 -#define CMD_VERIFY 0x1c03 +#define CMD_MASK 0xff3f +#define CMD_ASSIGN 0x040e +#define CMD_DEVICE_INQUIRY 0x1c0b +#define CMD_DMA_PACING_CONTROL 0x040d +#define CMD_FEATURE_CONTROL 0x040c +#define CMD_GET_POS_INFO 0x1c0a +#define CMD_INVALID_412 0x0412 +#define CMD_GET_COMPLETE_STATUS 0x1c07 +#define CMD_FORMAT_UNIT 0x1c16 +#define CMD_READ_DATA 0x1c01 +#define CMD_READ_DEVICE_CAPACITY 0x1c09 +#define CMD_REQUEST_SENSE 0x1c08 +#define CMD_RESET 0x0400 +#define CMD_SEND_OTHER_SCSI 0x241f +#define CMD_UNKNOWN_1C10 0x1c10 +#define CMD_UNKNOWN_1C11 0x1c11 +#define CMD_WRITE_DATA 0x1c02 +#define CMD_VERIFY 0x1c03 #define IRQ_TYPE_NONE 0x0 #define IRQ_TYPE_SCB_COMPLETE 0x1 @@ -206,244 +205,246 @@ typedef struct { #define IRQ_TYPE_SW_SEQ_ERROR 0xf #define IRQ_TYPE_RESET_COMPLETE 0x10 - #ifdef ENABLE_SPOCK_LOG int spock_do_log = ENABLE_SPOCK_LOG; - static void spock_log(const char *fmt, ...) { va_list ap; if (spock_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define spock_log(fmt, ...) +# define spock_log(fmt, ...) #endif static void spock_rethink_irqs(spock_t *scsi) { - int irq_pending = 0; - int c; + int irq_pending = 0; + int c; - if (!scsi->irq_status) { - for (c = 0; c < SCSI_ID_MAX; c++) { - if (scsi->irq_requests[c] != IRQ_TYPE_NONE) { - /* Found IRQ */ - scsi->irq_status = c | (scsi->irq_requests[c] << 4); - spock_log("Found IRQ: status = %02x\n", scsi->irq_status); - scsi->status |= STATUS_IRQ; - irq_pending = 1; - break; - } - } - } else + if (!scsi->irq_status) { + for (c = 0; c < SCSI_ID_MAX; c++) { + if (scsi->irq_requests[c] != IRQ_TYPE_NONE) { + /* Found IRQ */ + scsi->irq_status = c | (scsi->irq_requests[c] << 4); + spock_log("Found IRQ: status = %02x\n", scsi->irq_status); + scsi->status |= STATUS_IRQ; irq_pending = 1; - - if (scsi->basic_ctrl & CTRL_IRQ_ENA) { - if (irq_pending) { - spock_log("IRQ issued\n"); - scsi->irq_inactive = 0; - picint(1 << scsi->irq); - } else { - /* No IRQs pending, clear IRQ state */ - spock_log("IRQ cleared\n"); - scsi->irq_status = 0; - scsi->irq_inactive = 1; - scsi->status &= ~STATUS_IRQ; - picintc(1 << scsi->irq); - } - } else { - spock_log("IRQ disabled\n"); - picintc(1 << scsi->irq); + break; + } } + } else + irq_pending = 1; + + if (scsi->basic_ctrl & CTRL_IRQ_ENA) { + if (irq_pending) { + spock_log("IRQ issued\n"); + scsi->irq_inactive = 0; + picint(1 << scsi->irq); + } else { + /* No IRQs pending, clear IRQ state */ + spock_log("IRQ cleared\n"); + scsi->irq_status = 0; + scsi->irq_inactive = 1; + scsi->status &= ~STATUS_IRQ; + picintc(1 << scsi->irq); + } + } else { + spock_log("IRQ disabled\n"); + picintc(1 << scsi->irq); + } } static __inline void spock_set_irq(spock_t *scsi, int id, int type) { - spock_log("spock_set_irq id=%i type=%x %02x\n", id, type, scsi->irq_status); - scsi->irq_requests[id] = type; - if (!scsi->irq_status) /* Don't change IRQ status if one is currently being processed */ - spock_rethink_irqs(scsi); + spock_log("spock_set_irq id=%i type=%x %02x\n", id, type, scsi->irq_status); + scsi->irq_requests[id] = type; + if (!scsi->irq_status) /* Don't change IRQ status if one is currently being processed */ + spock_rethink_irqs(scsi); } static __inline void spock_clear_irq(spock_t *scsi, int id) { - spock_log("spock_clear_irq id=%i\n", id); - scsi->irq_requests[id] = IRQ_TYPE_NONE; - spock_rethink_irqs(scsi); + spock_log("spock_clear_irq id=%i\n", id); + scsi->irq_requests[id] = IRQ_TYPE_NONE; + spock_rethink_irqs(scsi); } static void spock_add_to_period(spock_t *scsi, int TransferLength) { - scsi->temp_period += (uint64_t) TransferLength; + scsi->temp_period += (uint64_t) TransferLength; } static void spock_write(uint16_t port, uint8_t val, void *p) { - spock_t *scsi = (spock_t *)p; + spock_t *scsi = (spock_t *) p; - spock_log("spock_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); + spock_log("spock_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); - switch (port & 7) { - case 0: case 1: case 2: case 3: /*Command Interface Register*/ - scsi->cir_pending[port & 3] = val; - if (port & 2) - scsi->cir_status |= 2; - else - scsi->cir_status |= 1; - break; + switch (port & 7) { + case 0: + case 1: + case 2: + case 3: /*Command Interface Register*/ + scsi->cir_pending[port & 3] = val; + if (port & 2) + scsi->cir_status |= 2; + else + scsi->cir_status |= 1; + break; - case 4: /*Attention Register*/ - scsi->attention_pending = val; - scsi->attention_wait = 2; - scsi->status |= STATUS_BUSY; - break; + case 4: /*Attention Register*/ + scsi->attention_pending = val; + scsi->attention_wait = 2; + scsi->status |= STATUS_BUSY; + break; - case 5: /*Basic Control Register*/ - if ((scsi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { - spock_log("Spock: SCSI reset and busy\n"); - scsi->in_reset = 1; - scsi->cmd_timer = SPOCK_TIME * 2; - scsi->status |= STATUS_BUSY; - } - scsi->basic_ctrl = val; - spock_rethink_irqs(scsi); - break; - } + case 5: /*Basic Control Register*/ + if ((scsi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { + spock_log("Spock: SCSI reset and busy\n"); + scsi->in_reset = 1; + scsi->cmd_timer = SPOCK_TIME * 2; + scsi->status |= STATUS_BUSY; + } + scsi->basic_ctrl = val; + spock_rethink_irqs(scsi); + break; + } } static void spock_writew(uint16_t port, uint16_t val, void *p) { - spock_t *scsi = (spock_t *)p; + spock_t *scsi = (spock_t *) p; - switch (port & 7) { - case 0: /*Command Interface Register*/ - scsi->cir_pending[0] = val & 0xff; - scsi->cir_pending[1] = val >> 8; - scsi->cir_status |= 1; - break; - case 2: /*Command Interface Register*/ - scsi->cir_pending[2] = val & 0xff; - scsi->cir_pending[3] = val >> 8; - scsi->cir_status |= 2; - break; - } + switch (port & 7) { + case 0: /*Command Interface Register*/ + scsi->cir_pending[0] = val & 0xff; + scsi->cir_pending[1] = val >> 8; + scsi->cir_status |= 1; + break; + case 2: /*Command Interface Register*/ + scsi->cir_pending[2] = val & 0xff; + scsi->cir_pending[3] = val >> 8; + scsi->cir_status |= 2; + break; + } - spock_log("spock_writew: port=%04x val=%04x\n", port, val); + spock_log("spock_writew: port=%04x val=%04x\n", port, val); } - static uint8_t spock_read(uint16_t port, void *p) { - spock_t *scsi = (spock_t *)p; - uint8_t temp = 0xff; + spock_t *scsi = (spock_t *) p; + uint8_t temp = 0xff; - switch (port & 7) { - case 0: case 1: case 2: case 3: /*Command Interface Register*/ - temp = scsi->cir_pending[port & 3]; - break; + switch (port & 7) { + case 0: + case 1: + case 2: + case 3: /*Command Interface Register*/ + temp = scsi->cir_pending[port & 3]; + break; - case 4: /*Attention Register*/ - temp = scsi->attention_pending; - break; - case 5: /*Basic Control Register*/ - temp = scsi->basic_ctrl; - break; - case 6: /*IRQ status*/ - temp = scsi->irq_status; - break; - case 7: /*Basic Status Register*/ - temp = scsi->status; - spock_log("Cir Status=%d\n", scsi->cir_status); - if (scsi->cir_status == 0) { - spock_log("Status Cmd Empty\n"); - temp |= STATUS_CMD_EMPTY; - } - else if (scsi->cir_status == 3) { - spock_log("Status Cmd Full\n"); - temp |= STATUS_CMD_FULL; - } - break; - } + case 4: /*Attention Register*/ + temp = scsi->attention_pending; + break; + case 5: /*Basic Control Register*/ + temp = scsi->basic_ctrl; + break; + case 6: /*IRQ status*/ + temp = scsi->irq_status; + break; + case 7: /*Basic Status Register*/ + temp = scsi->status; + spock_log("Cir Status=%d\n", scsi->cir_status); + if (scsi->cir_status == 0) { + spock_log("Status Cmd Empty\n"); + temp |= STATUS_CMD_EMPTY; + } else if (scsi->cir_status == 3) { + spock_log("Status Cmd Full\n"); + temp |= STATUS_CMD_FULL; + } + break; + } - spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x %02x\n", port, temp, CS, cs, cpu_state.pc, BH); - return temp; + spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x %02x\n", port, temp, CS, cs, cpu_state.pc, BH); + return temp; } static uint16_t spock_readw(uint16_t port, void *p) { - spock_t *scsi = (spock_t *)p; - uint16_t temp = 0xffff; + spock_t *scsi = (spock_t *) p; + uint16_t temp = 0xffff; - switch (port & 7) { - case 0: /*Command Interface Register*/ - temp = scsi->cir_pending[0] | (scsi->cir_pending[1] << 8); - break; - case 2: /*Command Interface Register*/ - temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); - break; - } + switch (port & 7) { + case 0: /*Command Interface Register*/ + temp = scsi->cir_pending[0] | (scsi->cir_pending[1] << 8); + break; + case 2: /*Command Interface Register*/ + temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); + break; + } - spock_log("spock_readw: port=%04x val=%04x\n", port, temp); - return temp; + spock_log("spock_readw: port=%04x val=%04x\n", port, temp); + return temp; } static void spock_rd_sge(spock_t *scsi, uint32_t Address, SGE *SG) { - dma_bm_read(Address, (uint8_t *)SG, sizeof(SGE), 2); - spock_add_to_period(scsi, sizeof(SGE)); + dma_bm_read(Address, (uint8_t *) SG, sizeof(SGE), 2); + spock_add_to_period(scsi, sizeof(SGE)); } static int spock_get_len(spock_t *scsi, scb_t *scb) { - uint32_t DataToTransfer = 0, i = 0; + uint32_t DataToTransfer = 0, i = 0; - spock_log("Data Buffer write: length %d, pointer 0x%04X\n", - scsi->data_len, scsi->data_ptr); + spock_log("Data Buffer write: length %d, pointer 0x%04X\n", + scsi->data_len, scsi->data_ptr); - if (!scsi->data_len) - return(0); + if (!scsi->data_len) + return (0); - if (scb->enable & ENABLE_PT) { - for (i = 0; i < scsi->data_len; i += 8) { - spock_rd_sge(scsi, scsi->data_ptr + i, &scb->sge); + if (scb->enable & ENABLE_PT) { + for (i = 0; i < scsi->data_len; i += 8) { + spock_rd_sge(scsi, scsi->data_ptr + i, &scb->sge); - DataToTransfer += scb->sge.sys_buf_byte_count; - } - return(DataToTransfer); - } else { - return(scsi->data_len); - } + DataToTransfer += scb->sge.sys_buf_byte_count; + } + return (DataToTransfer); + } else { + return (scsi->data_len); + } } static void spock_process_imm_cmd(spock_t *scsi) { - int i; - int adapter_id, phys_id, lun_id; + int i; + int adapter_id, phys_id, lun_id; switch (scsi->command & CMD_MASK) { case CMD_ASSIGN: adapter_id = (scsi->command >> 16) & 15; - phys_id = (scsi->command >> 20) & 7; - lun_id = (scsi->command >> 24) & 7; - if (adapter_id == 15) { + phys_id = (scsi->command >> 20) & 7; + lun_id = (scsi->command >> 24) & 7; + if (adapter_id == 15) { if (phys_id == 7) /*Device 15 always adapter*/ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); else /*Can not re-assign device 15 (always adapter)*/ @@ -456,7 +457,7 @@ spock_process_imm_cmd(spock_t *scsi) } else { if (phys_id != scsi->adapter_id) { scsi->dev_id[adapter_id].phys_id = phys_id; - scsi->dev_id[adapter_id].lun_id = lun_id; + scsi->dev_id[adapter_id].lun_id = lun_id; spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id); spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); } else { /*Can not assign adapter*/ @@ -465,8 +466,8 @@ spock_process_imm_cmd(spock_t *scsi) } } } - break; - case CMD_DMA_PACING_CONTROL: + break; + case CMD_DMA_PACING_CONTROL: scsi->pacing = scsi->cir[2]; spock_log("Pacing control: %i\n", scsi->pacing); spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); @@ -491,7 +492,7 @@ spock_process_imm_cmd(spock_t *scsi) scsi->adapter_reset = 1; scsi->scb_state = 0; - } + } spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); break; @@ -504,17 +505,17 @@ spock_process_imm_cmd(spock_t *scsi) static void spock_execute_cmd(spock_t *scsi, scb_t *scb) { - int c; - int old_scb_state; + int c; + int old_scb_state; - if (scsi->in_reset) { - spock_log("Reset type = %d\n", scsi->in_reset); + if (scsi->in_reset) { + spock_log("Reset type = %d\n", scsi->in_reset); - scsi->status &= ~STATUS_BUSY; - scsi->irq_status = 0; + scsi->status &= ~STATUS_BUSY; + scsi->irq_status = 0; - for (c = 0; c < SCSI_ID_MAX; c++) - spock_clear_irq(scsi, c); + for (c = 0; c < SCSI_ID_MAX; c++) + spock_clear_irq(scsi, c); if (scsi->in_reset == 1) { scsi->basic_ctrl |= CTRL_IRQ_ENA; @@ -522,36 +523,35 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) } else spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE); - /*Reset device mappings*/ - for (c = 0; c < 7; c++) { - scsi->dev_id[c].phys_id = c; - scsi->dev_id[c].lun_id = 0; - } - for (; c < (SCSI_ID_MAX-1); c++) - scsi->dev_id[c].phys_id = -1; + /*Reset device mappings*/ + for (c = 0; c < 7; c++) { + scsi->dev_id[c].phys_id = c; + scsi->dev_id[c].lun_id = 0; + } + for (; c < (SCSI_ID_MAX - 1); c++) + scsi->dev_id[c].phys_id = -1; - scsi->in_reset = 0; - return; - } + scsi->in_reset = 0; + return; + } - if (scsi->in_invalid) { - spock_log("Invalid command\n"); - spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_ERROR); - scsi->in_invalid = 0; - return; - } + if (scsi->in_invalid) { + spock_log("Invalid command\n"); + spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_ERROR); + scsi->in_invalid = 0; + return; + } - spock_log("SCB State = %d\n", scsi->scb_state); + spock_log("SCB State = %d\n", scsi->scb_state); - do - { - old_scb_state = scsi->scb_state; + do { + old_scb_state = scsi->scb_state; - switch (scsi->scb_state) { - case 0: /* Idle */ - break; + switch (scsi->scb_state) { + case 0: /* Idle */ + break; - case 1: /* Select */ + case 1: /* Select */ if (scsi->dev_id[scsi->scb_id].phys_id == -1) { uint16_t term_stat_block_addr7 = (0xe << 8) | 0; uint16_t term_stat_block_addr8 = (0xa << 8) | 0; @@ -559,246 +559,246 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) spock_log("Start failed, SCB ID = %d\n", scsi->scb_id); spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); scsi->scb_state = 0; - dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2); - dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0x7 * 2, (uint8_t *) &term_stat_block_addr7, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0x8 * 2, (uint8_t *) &term_stat_block_addr8, 2, 2); break; } - dma_bm_read(scsi->scb_addr, (uint8_t *)&scb->command, 2, 2); - dma_bm_read(scsi->scb_addr + 2, (uint8_t *)&scb->enable, 2, 2); - dma_bm_read(scsi->scb_addr + 4, (uint8_t *)&scb->lba_addr, 4, 2); - dma_bm_read(scsi->scb_addr + 8, (uint8_t *)&scb->sge.sys_buf_addr, 4, 2); - dma_bm_read(scsi->scb_addr + 12, (uint8_t *)&scb->sge.sys_buf_byte_count, 4, 2); - dma_bm_read(scsi->scb_addr + 16, (uint8_t *)&scb->term_status_block_addr, 4, 2); - dma_bm_read(scsi->scb_addr + 20, (uint8_t *)&scb->scb_chain_addr, 4, 2); - dma_bm_read(scsi->scb_addr + 24, (uint8_t *)&scb->block_count, 2, 2); - dma_bm_read(scsi->scb_addr + 26, (uint8_t *)&scb->block_length, 2, 2); + dma_bm_read(scsi->scb_addr, (uint8_t *) &scb->command, 2, 2); + dma_bm_read(scsi->scb_addr + 2, (uint8_t *) &scb->enable, 2, 2); + dma_bm_read(scsi->scb_addr + 4, (uint8_t *) &scb->lba_addr, 4, 2); + dma_bm_read(scsi->scb_addr + 8, (uint8_t *) &scb->sge.sys_buf_addr, 4, 2); + dma_bm_read(scsi->scb_addr + 12, (uint8_t *) &scb->sge.sys_buf_byte_count, 4, 2); + dma_bm_read(scsi->scb_addr + 16, (uint8_t *) &scb->term_status_block_addr, 4, 2); + dma_bm_read(scsi->scb_addr + 20, (uint8_t *) &scb->scb_chain_addr, 4, 2); + dma_bm_read(scsi->scb_addr + 24, (uint8_t *) &scb->block_count, 2, 2); + dma_bm_read(scsi->scb_addr + 26, (uint8_t *) &scb->block_length, 2, 2); - spock_log("SCB : \n" - " Command = %04x\n" - " Enable = %04x\n" - " LBA addr = %08x\n" - " System buffer addr = %08x\n" - " System buffer byte count = %08x\n" - " Terminate status block addr = %08x\n" - " SCB chain address = %08x\n" - " Block count = %04x\n" - " Block length = %04x\n" - " SCB id = %d, Phys id = %d\n", - scb->command, scb->enable, scb->lba_addr, - scb->sge.sys_buf_addr, scb->sge.sys_buf_byte_count, - scb->term_status_block_addr, scb->scb_chain_addr, - scb->block_count, scb->block_length, scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id); + spock_log("SCB : \n" + " Command = %04x\n" + " Enable = %04x\n" + " LBA addr = %08x\n" + " System buffer addr = %08x\n" + " System buffer byte count = %08x\n" + " Terminate status block addr = %08x\n" + " SCB chain address = %08x\n" + " Block count = %04x\n" + " Block length = %04x\n" + " SCB id = %d, Phys id = %d\n", + scb->command, scb->enable, scb->lba_addr, + scb->sge.sys_buf_addr, scb->sge.sys_buf_byte_count, + scb->term_status_block_addr, scb->scb_chain_addr, + scb->block_count, scb->block_length, scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id); - switch (scb->command & CMD_MASK) { - case CMD_GET_COMPLETE_STATUS: - { - spock_log("Get Complete Status\n"); - get_complete_stat_t *get_complete_stat = &scsi->get_complete_stat; + switch (scb->command & CMD_MASK) { + case CMD_GET_COMPLETE_STATUS: + { + spock_log("Get Complete Status\n"); + get_complete_stat_t *get_complete_stat = &scsi->get_complete_stat; - get_complete_stat->scb_status = 0x201; - get_complete_stat->retry_count = 0; - get_complete_stat->residual_byte_count = 0; - get_complete_stat->sg_list_element_addr = 0; - get_complete_stat->device_dep_status_len = 0x0c; - get_complete_stat->cmd_status = scsi->cmd_status << 8; - get_complete_stat->error = 0; - get_complete_stat->reserved = 0; - get_complete_stat->cache_info_status = 0; - get_complete_stat->scb_addr = scsi->scb_addr; + get_complete_stat->scb_status = 0x201; + get_complete_stat->retry_count = 0; + get_complete_stat->residual_byte_count = 0; + get_complete_stat->sg_list_element_addr = 0; + get_complete_stat->device_dep_status_len = 0x0c; + get_complete_stat->cmd_status = scsi->cmd_status << 8; + get_complete_stat->error = 0; + get_complete_stat->reserved = 0; + get_complete_stat->cache_info_status = 0; + get_complete_stat->scb_addr = scsi->scb_addr; - dma_bm_write(scb->sge.sys_buf_addr, (uint8_t *)&get_complete_stat->scb_status, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_complete_stat->retry_count, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_complete_stat->residual_byte_count, 4, 2); - dma_bm_write(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_complete_stat->sg_list_element_addr, 4, 2); - dma_bm_write(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_complete_stat->device_dep_status_len, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_complete_stat->cmd_status, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_complete_stat->error, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 18, (uint8_t *)&get_complete_stat->reserved, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 20, (uint8_t *)&get_complete_stat->cache_info_status, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 22, (uint8_t *)&get_complete_stat->scb_addr, 4, 2); - scsi->scb_state = 3; - } - break; + dma_bm_write(scb->sge.sys_buf_addr, (uint8_t *) &get_complete_stat->scb_status, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 2, (uint8_t *) &get_complete_stat->retry_count, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 4, (uint8_t *) &get_complete_stat->residual_byte_count, 4, 2); + dma_bm_write(scb->sge.sys_buf_addr + 8, (uint8_t *) &get_complete_stat->sg_list_element_addr, 4, 2); + dma_bm_write(scb->sge.sys_buf_addr + 12, (uint8_t *) &get_complete_stat->device_dep_status_len, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 14, (uint8_t *) &get_complete_stat->cmd_status, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 16, (uint8_t *) &get_complete_stat->error, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 18, (uint8_t *) &get_complete_stat->reserved, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 20, (uint8_t *) &get_complete_stat->cache_info_status, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 22, (uint8_t *) &get_complete_stat->scb_addr, 4, 2); + scsi->scb_state = 3; + } + break; - case CMD_UNKNOWN_1C10: - spock_log("Unknown 1C10\n"); - dma_bm_read(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count, 2); - scsi->scb_state = 3; - break; + case CMD_UNKNOWN_1C10: + spock_log("Unknown 1C10\n"); + dma_bm_read(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count, 2); + scsi->scb_state = 3; + break; - case CMD_UNKNOWN_1C11: - spock_log("Unknown 1C11\n"); - dma_bm_write(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count, 2); - scsi->scb_state = 3; - break; + case CMD_UNKNOWN_1C11: + spock_log("Unknown 1C11\n"); + dma_bm_write(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count, 2); + scsi->scb_state = 3; + break; - case CMD_GET_POS_INFO: - { - spock_log("Get POS Info\n"); - get_pos_info_t *get_pos_info = &scsi->get_pos_info; + case CMD_GET_POS_INFO: + { + spock_log("Get POS Info\n"); + get_pos_info_t *get_pos_info = &scsi->get_pos_info; - get_pos_info->pos = 0x8eff; - get_pos_info->pos1 = scsi->pos_regs[3] | (scsi->pos_regs[2] << 8); - get_pos_info->pos2 = 0x0e | (scsi->pos_regs[4] << 8); - get_pos_info->pos3 = 1 << 12; - get_pos_info->pos4 = (7 << 8) | 8; - get_pos_info->pos5 = (16 << 8) | scsi->pacing; - get_pos_info->pos6 = (30 << 8) | 1; - get_pos_info->pos7 = 0; - get_pos_info->pos8 = 0; + get_pos_info->pos = 0x8eff; + get_pos_info->pos1 = scsi->pos_regs[3] | (scsi->pos_regs[2] << 8); + get_pos_info->pos2 = 0x0e | (scsi->pos_regs[4] << 8); + get_pos_info->pos3 = 1 << 12; + get_pos_info->pos4 = (7 << 8) | 8; + get_pos_info->pos5 = (16 << 8) | scsi->pacing; + get_pos_info->pos6 = (30 << 8) | 1; + get_pos_info->pos7 = 0; + get_pos_info->pos8 = 0; - dma_bm_write(scb->sge.sys_buf_addr, (uint8_t *)&get_pos_info->pos, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_pos_info->pos1, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_pos_info->pos2, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 6, (uint8_t *)&get_pos_info->pos3, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_pos_info->pos4, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 10, (uint8_t *)&get_pos_info->pos5, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_pos_info->pos6, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_pos_info->pos7, 2, 2); - dma_bm_write(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_pos_info->pos8, 2, 2); - scsi->scb_state = 3; - } - break; + dma_bm_write(scb->sge.sys_buf_addr, (uint8_t *) &get_pos_info->pos, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 2, (uint8_t *) &get_pos_info->pos1, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 4, (uint8_t *) &get_pos_info->pos2, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 6, (uint8_t *) &get_pos_info->pos3, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 8, (uint8_t *) &get_pos_info->pos4, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 10, (uint8_t *) &get_pos_info->pos5, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 12, (uint8_t *) &get_pos_info->pos6, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 14, (uint8_t *) &get_pos_info->pos7, 2, 2); + dma_bm_write(scb->sge.sys_buf_addr + 16, (uint8_t *) &get_pos_info->pos8, 2, 2); + scsi->scb_state = 3; + } + break; - case CMD_DEVICE_INQUIRY: - if (scb->command != CMD_DEVICE_INQUIRY) + case CMD_DEVICE_INQUIRY: + if (scb->command != CMD_DEVICE_INQUIRY) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id); - scsi->cdb[0] = GPCMD_INQUIRY; - scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb[2] = 0; /*Page code*/ - scsi->cdb[3] = 0; - scsi->cdb[4] = scb->sge.sys_buf_byte_count; /*Allocation length*/ - scsi->cdb[5] = 0; /*Control*/ - scsi->cdb_len = 6; - scsi->data_ptr = scb->sge.sys_buf_addr; - scsi->data_len = scb->sge.sys_buf_byte_count; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; + spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id); + scsi->cdb[0] = GPCMD_INQUIRY; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = 0; /*Page code*/ + scsi->cdb[3] = 0; + scsi->cdb[4] = scb->sge.sys_buf_byte_count; /*Allocation length*/ + scsi->cdb[5] = 0; /*Control*/ + scsi->cdb_len = 6; + scsi->data_ptr = scb->sge.sys_buf_addr; + scsi->data_len = scb->sge.sys_buf_byte_count; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; - case CMD_SEND_OTHER_SCSI: - if (scb->command != CMD_SEND_OTHER_SCSI) + case CMD_SEND_OTHER_SCSI: + if (scb->command != CMD_SEND_OTHER_SCSI) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset); - dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2); - scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ - scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; + spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset); + dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2); + scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ + scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; - case CMD_READ_DEVICE_CAPACITY: - if (scb->command != CMD_READ_DEVICE_CAPACITY) + case CMD_READ_DEVICE_CAPACITY: + if (scb->command != CMD_READ_DEVICE_CAPACITY) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset); - scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY; - scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb[2] = 0; /*LBA*/ - scsi->cdb[3] = 0; - scsi->cdb[4] = 0; - scsi->cdb[5] = 0; - scsi->cdb[6] = 0; /*Reserved*/ - scsi->cdb[7] = 0; - scsi->cdb[8] = 0; - scsi->cdb[9] = 0; /*Control*/ - scsi->cdb_len = 10; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; + spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset); + scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = 0; /*LBA*/ + scsi->cdb[3] = 0; + scsi->cdb[4] = 0; + scsi->cdb[5] = 0; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = 0; + scsi->cdb[8] = 0; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; - case CMD_READ_DATA: - if (scb->command != CMD_READ_DATA) + case CMD_READ_DATA: + if (scb->command != CMD_READ_DATA) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset); - scsi->cdb[0] = GPCMD_READ_10; - scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ - scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; - scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; - scsi->cdb[5] = scb->lba_addr & 0xff; - scsi->cdb[6] = 0; /*Reserved*/ - scsi->cdb[7] = (scb->block_count >> 8) & 0xff; - scsi->cdb[8] = scb->block_count & 0xff; - scsi->cdb[9] = 0; /*Control*/ - scsi->cdb_len = 10; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; + spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset); + scsi->cdb[0] = GPCMD_READ_10; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb[5] = scb->lba_addr & 0xff; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb[8] = scb->block_count & 0xff; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; - case CMD_WRITE_DATA: - if (scb->command != CMD_WRITE_DATA) + case CMD_WRITE_DATA: + if (scb->command != CMD_WRITE_DATA) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Device Write Data\n"); - scsi->cdb[0] = GPCMD_WRITE_10; - scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ - scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; - scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; - scsi->cdb[5] = scb->lba_addr & 0xff; - scsi->cdb[6] = 0; /*Reserved*/ - scsi->cdb[7] = (scb->block_count >> 8) & 0xff; - scsi->cdb[8] = scb->block_count & 0xff; - scsi->cdb[9] = 0; /*Control*/ - scsi->cdb_len = 10; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; + spock_log("Device Write Data\n"); + scsi->cdb[0] = GPCMD_WRITE_10; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb[5] = scb->lba_addr & 0xff; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb[8] = scb->block_count & 0xff; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; - case CMD_VERIFY: - if (scb->command != CMD_VERIFY) + case CMD_VERIFY: + if (scb->command != CMD_VERIFY) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Device Verify\n"); - scsi->cdb[0] = GPCMD_VERIFY_10; - scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ - scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; - scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; - scsi->cdb[5] = scb->lba_addr & 0xff; - scsi->cdb[6] = 0; /*Reserved*/ - scsi->cdb[7] = (scb->block_count >> 8) & 0xff; - scsi->cdb[8] = scb->block_count & 0xff; - scsi->cdb[9] = 0; /*Control*/ - scsi->cdb_len = 10; - scsi->data_len = 0; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; + spock_log("Device Verify\n"); + scsi->cdb[0] = GPCMD_VERIFY_10; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb[5] = scb->lba_addr & 0xff; + scsi->cdb[6] = 0; /*Reserved*/ + scsi->cdb[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb[8] = scb->block_count & 0xff; + scsi->cdb[9] = 0; /*Control*/ + scsi->cdb_len = 10; + scsi->data_len = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; - case CMD_REQUEST_SENSE: - if (scb->command != CMD_REQUEST_SENSE) + case CMD_REQUEST_SENSE: + if (scb->command != CMD_REQUEST_SENSE) scsi->cdb_id = scsi->scb_id; else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id); - scsi->cdb[0] = GPCMD_REQUEST_SENSE; - scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb[2] = 0; - scsi->cdb[3] = 0; - scsi->cdb[4] = scb->sge.sys_buf_byte_count; /*Allocation length*/ - scsi->cdb[5] = 0; - scsi->cdb_len = 6; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = 2; - return; - } - break; + spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id); + scsi->cdb[0] = GPCMD_REQUEST_SENSE; + scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb[2] = 0; + scsi->cdb[3] = 0; + scsi->cdb[4] = scb->sge.sys_buf_byte_count; /*Allocation length*/ + scsi->cdb[5] = 0; + scsi->cdb_len = 6; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = 2; + return; + } + break; - case 2: /* Wait */ - if (scsi->scsi_state == SCSI_STATE_IDLE) { + case 2: /* Wait */ + if (scsi->scsi_state == SCSI_STATE_IDLE) { if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) { if (scsi->last_status == SCSI_STATUS_OK) { scsi->scb_state = 3; @@ -812,10 +812,10 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); scsi->scb_state = 0; spock_log("Status Check Condition on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset); - dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2); - dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2); - dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2); - dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0x7 * 2, (uint8_t *) &term_stat_block_addr7, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0x8 * 2, (uint8_t *) &term_stat_block_addr8, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0xb * 2, (uint8_t *) &term_stat_block_addrb, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0xc * 2, (uint8_t *) &term_stat_block_addrc, 2, 2); } } else { uint16_t term_stat_block_addr7 = (0xc << 8) | 2; @@ -823,343 +823,343 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); scsi->scb_state = 0; spock_log("Status Check Condition on device ID %d on no device, reset = %d\n", scsi->scb_id, scsi->adapter_reset); - dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2); - dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0x7 * 2, (uint8_t *) &term_stat_block_addr7, 2, 2); + dma_bm_write(scb->term_status_block_addr + 0x8 * 2, (uint8_t *) &term_stat_block_addr8, 2, 2); } - } - break; + } + break; - case 3: /* Complete */ - if (scb->enable & 1) { - scsi->scb_state = 1; - scsi->scb_addr = scb->scb_chain_addr; - spock_log("Next SCB - %08x\n", scsi->scb_addr); - } else { - spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); - scsi->scb_state = 0; - spock_log("Complete SCB\n"); - } - break; - } - } while (scsi->scb_state != old_scb_state); + case 3: /* Complete */ + if (scb->enable & 1) { + scsi->scb_state = 1; + scsi->scb_addr = scb->scb_chain_addr; + spock_log("Next SCB - %08x\n", scsi->scb_addr); + } else { + spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); + scsi->scb_state = 0; + spock_log("Complete SCB\n"); + } + break; + } + } while (scsi->scb_state != old_scb_state); } static void spock_process_scsi(spock_t *scsi, scb_t *scb) { - int c; - double p; - scsi_device_t *sd; + int c; + double p; + scsi_device_t *sd; - switch (scsi->scsi_state) { - case SCSI_STATE_IDLE: - break; + switch (scsi->scsi_state) { + case SCSI_STATE_IDLE: + break; - case SCSI_STATE_SELECT: - spock_log("Selecting ID %d\n", scsi->cdb_id); - if ((scsi->cdb_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) { - scsi->scsi_state = SCSI_STATE_SEND_COMMAND; - spock_log("Device selected at ID %i\n", scsi->cdb_id); - } else { - spock_log("Device selection failed at ID %i\n", scsi->cdb_id); - scsi->scsi_state = SCSI_STATE_IDLE; - if (!scsi->cmd_timer) { - spock_log("Callback to reset\n"); - scsi->cmd_timer = 1; - } - spock_add_to_period(scsi, 1); - } - break; + case SCSI_STATE_SELECT: + spock_log("Selecting ID %d\n", scsi->cdb_id); + if ((scsi->cdb_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) { + scsi->scsi_state = SCSI_STATE_SEND_COMMAND; + spock_log("Device selected at ID %i\n", scsi->cdb_id); + } else { + spock_log("Device selection failed at ID %i\n", scsi->cdb_id); + scsi->scsi_state = SCSI_STATE_IDLE; + if (!scsi->cmd_timer) { + spock_log("Callback to reset\n"); + scsi->cmd_timer = 1; + } + spock_add_to_period(scsi, 1); + } + break; - case SCSI_STATE_SEND_COMMAND: - sd = &scsi_devices[scsi->bus][scsi->cdb_id]; - memset(scsi->temp_cdb, 0x00, 12); + case SCSI_STATE_SEND_COMMAND: + sd = &scsi_devices[scsi->bus][scsi->cdb_id]; + memset(scsi->temp_cdb, 0x00, 12); - if (scsi->cdb_len < 12) { - memcpy(scsi->temp_cdb, scsi->cdb, - scsi->cdb_len); - spock_add_to_period(scsi, scsi->cdb_len); - } else { - memcpy(scsi->temp_cdb, scsi->cdb, - 12); - spock_add_to_period(scsi, 12); - } + if (scsi->cdb_len < 12) { + memcpy(scsi->temp_cdb, scsi->cdb, + scsi->cdb_len); + spock_add_to_period(scsi, scsi->cdb_len); + } else { + memcpy(scsi->temp_cdb, scsi->cdb, + 12); + spock_add_to_period(scsi, 12); + } - scsi->data_ptr = scb->sge.sys_buf_addr; - scsi->data_len = scb->sge.sys_buf_byte_count; + scsi->data_ptr = scb->sge.sys_buf_addr; + scsi->data_len = scb->sge.sys_buf_byte_count; - if (scb->enable & 0x400) - sd->buffer_length = -1; - else - sd->buffer_length = spock_get_len(scsi, scb); + if (scb->enable & 0x400) + sd->buffer_length = -1; + else + sd->buffer_length = spock_get_len(scsi, scb); - scsi_device_command_phase0(sd, scsi->temp_cdb); - spock_log("SCSI ID %i: Current CDB[0] = %02x, LUN = %i, data len = %i, max len = %i, phase val = %02x\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1] >> 5, sd->buffer_length, spock_get_len(scsi, scb), sd->phase); + scsi_device_command_phase0(sd, scsi->temp_cdb); + spock_log("SCSI ID %i: Current CDB[0] = %02x, LUN = %i, data len = %i, max len = %i, phase val = %02x\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1] >> 5, sd->buffer_length, spock_get_len(scsi, scb), sd->phase); - if (sd->phase != SCSI_PHASE_STATUS && sd->buffer_length > 0) { - p = scsi_device_get_callback(sd); - if (p <= 0.0) - spock_add_to_period(scsi, sd->buffer_length); - else - scsi->media_period += p; + if (sd->phase != SCSI_PHASE_STATUS && sd->buffer_length > 0) { + p = scsi_device_get_callback(sd); + if (p <= 0.0) + spock_add_to_period(scsi, sd->buffer_length); + else + scsi->media_period += p; - if (scb->enable & ENABLE_PT) { - int32_t buflen = sd->buffer_length; - int sg_pos = 0; - uint32_t DataTx = 0; - uint32_t Address; + if (scb->enable & ENABLE_PT) { + int32_t buflen = sd->buffer_length; + int sg_pos = 0; + uint32_t DataTx = 0; + uint32_t Address; - if (scb->sge.sys_buf_byte_count > 0) { - for (c = 0; c < scsi->data_len; c += 8) { - spock_rd_sge(scsi, scsi->data_ptr + c, &scb->sge); + if (scb->sge.sys_buf_byte_count > 0) { + for (c = 0; c < scsi->data_len; c += 8) { + spock_rd_sge(scsi, scsi->data_ptr + c, &scb->sge); - Address = scb->sge.sys_buf_addr; - DataTx = MIN((int) scb->sge.sys_buf_byte_count, buflen); + Address = scb->sge.sys_buf_addr; + DataTx = MIN((int) scb->sge.sys_buf_byte_count, buflen); - if ((sd->phase == SCSI_PHASE_DATA_IN) && DataTx) { - spock_log("Writing S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address); - dma_bm_write(Address, &sd->sc->temp_buffer[sg_pos], DataTx, 2); - } else if ((sd->phase == SCSI_PHASE_DATA_OUT) && DataTx) { - spock_log("Reading S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address); - dma_bm_read(Address, &sd->sc->temp_buffer[sg_pos], DataTx, 2); - } + if ((sd->phase == SCSI_PHASE_DATA_IN) && DataTx) { + spock_log("Writing S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address); + dma_bm_write(Address, &sd->sc->temp_buffer[sg_pos], DataTx, 2); + } else if ((sd->phase == SCSI_PHASE_DATA_OUT) && DataTx) { + spock_log("Reading S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address); + dma_bm_read(Address, &sd->sc->temp_buffer[sg_pos], DataTx, 2); + } - sg_pos += scb->sge.sys_buf_byte_count; - buflen -= scb->sge.sys_buf_byte_count; + sg_pos += scb->sge.sys_buf_byte_count; + buflen -= scb->sge.sys_buf_byte_count; - if (buflen < 0) - buflen = 0; - } - } - } else { - spock_log("Normal Transfer\n"); - if (sd->phase == SCSI_PHASE_DATA_IN) { - dma_bm_write(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len), 2); - } else if (sd->phase == SCSI_PHASE_DATA_OUT) - dma_bm_read(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len), 2); - } + if (buflen < 0) + buflen = 0; + } + } + } else { + spock_log("Normal Transfer\n"); + if (sd->phase == SCSI_PHASE_DATA_IN) { + dma_bm_write(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int) scsi->data_len), 2); + } else if (sd->phase == SCSI_PHASE_DATA_OUT) + dma_bm_read(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int) scsi->data_len), 2); + } - scsi_device_command_phase1(sd); - } - scsi->last_status = sd->status; - scsi->scsi_state = SCSI_STATE_END_PHASE; - break; + scsi_device_command_phase1(sd); + } + scsi->last_status = sd->status; + scsi->scsi_state = SCSI_STATE_END_PHASE; + break; - case SCSI_STATE_END_PHASE: - scsi->scsi_state = SCSI_STATE_IDLE; + case SCSI_STATE_END_PHASE: + scsi->scsi_state = SCSI_STATE_IDLE; - spock_log("State to idle, cmd timer %d\n", scsi->cmd_timer); - if (!scsi->cmd_timer) { - scsi->cmd_timer = 1; - } - spock_add_to_period(scsi, 1); - break; - } + spock_log("State to idle, cmd timer %d\n", scsi->cmd_timer); + if (!scsi->cmd_timer) { + scsi->cmd_timer = 1; + } + spock_add_to_period(scsi, 1); + break; + } } static void spock_callback(void *priv) { - double period; - spock_t *scsi = (spock_t *)priv; - scb_t *scb = &scsi->scb; + double period; + spock_t *scsi = (spock_t *) priv; + scb_t *scb = &scsi->scb; - scsi->temp_period = 0; - scsi->media_period = 0.0; + scsi->temp_period = 0; + scsi->media_period = 0.0; - if (scsi->cmd_timer) { - scsi->cmd_timer--; - if (!scsi->cmd_timer) { - spock_execute_cmd(scsi, scb); - } - } + if (scsi->cmd_timer) { + scsi->cmd_timer--; + if (!scsi->cmd_timer) { + spock_execute_cmd(scsi, scb); + } + } - if (scsi->attention_wait && - (scsi->scb_state == 0 || (scsi->attention_pending & 0xf0) == 0xe0)) { - scsi->attention_wait--; - if (!scsi->attention_wait) { - scsi->attention = scsi->attention_pending; - scsi->status &= ~STATUS_BUSY; - scsi->cir[0] = scsi->cir_pending[0]; - scsi->cir[1] = scsi->cir_pending[1]; - scsi->cir[2] = scsi->cir_pending[2]; - scsi->cir[3] = scsi->cir_pending[3]; - scsi->cir_status = 0; + if (scsi->attention_wait && (scsi->scb_state == 0 || (scsi->attention_pending & 0xf0) == 0xe0)) { + scsi->attention_wait--; + if (!scsi->attention_wait) { + scsi->attention = scsi->attention_pending; + scsi->status &= ~STATUS_BUSY; + scsi->cir[0] = scsi->cir_pending[0]; + scsi->cir[1] = scsi->cir_pending[1]; + scsi->cir[2] = scsi->cir_pending[2]; + scsi->cir[3] = scsi->cir_pending[3]; + scsi->cir_status = 0; - switch (scsi->attention >> 4) { - case 1: /*Immediate command*/ - scsi->cmd_status = 0x0a; - scsi->command = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); - switch (scsi->command & CMD_MASK) { - case CMD_ASSIGN: - case CMD_DMA_PACING_CONTROL: - case CMD_FEATURE_CONTROL: - case CMD_INVALID_412: - case CMD_RESET: - spock_process_imm_cmd(scsi); - break; - } - break; + switch (scsi->attention >> 4) { + case 1: /*Immediate command*/ + scsi->cmd_status = 0x0a; + scsi->command = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + switch (scsi->command & CMD_MASK) { + case CMD_ASSIGN: + case CMD_DMA_PACING_CONTROL: + case CMD_FEATURE_CONTROL: + case CMD_INVALID_412: + case CMD_RESET: + spock_process_imm_cmd(scsi); + break; + } + break; - case 3: case 4: case 0x0f: /*Start SCB*/ - scsi->cmd_status = 1; - scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); - scsi->scb_id = scsi->attention & 0x0f; - scsi->cmd_timer = SPOCK_TIME * 2; - spock_log("Start SCB at ID = %d\n", scsi->scb_id); - scsi->scb_state = 1; - break; + case 3: + case 4: + case 0x0f: /*Start SCB*/ + scsi->cmd_status = 1; + scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + scsi->scb_id = scsi->attention & 0x0f; + scsi->cmd_timer = SPOCK_TIME * 2; + spock_log("Start SCB at ID = %d\n", scsi->scb_id); + scsi->scb_state = 1; + break; - case 5: /*Invalid*/ - case 0x0a: /*Invalid*/ - scsi->in_invalid = 1; - scsi->cmd_timer = SPOCK_TIME * 2; - break; + case 5: /*Invalid*/ + case 0x0a: /*Invalid*/ + scsi->in_invalid = 1; + scsi->cmd_timer = SPOCK_TIME * 2; + break; - case 0x0e: /*EOI*/ - scsi->irq_status = 0; - spock_clear_irq(scsi, scsi->attention & 0xf); - break; - } - } - } + case 0x0e: /*EOI*/ + scsi->irq_status = 0; + spock_clear_irq(scsi, scsi->attention & 0xf); + break; + } + } + } - spock_process_scsi(scsi, scb); + spock_process_scsi(scsi, scb); - period = 0.2 * ((double) scsi->temp_period); - timer_on(&scsi->callback_timer, (scsi->media_period + period + 10.0), 0); - spock_log("Temporary period: %lf us (%" PRIi64 " periods)\n", scsi->callback_timer.period, scsi->temp_period); + period = 0.2 * ((double) scsi->temp_period); + timer_on(&scsi->callback_timer, (scsi->media_period + period + 10.0), 0); + spock_log("Temporary period: %lf us (%" PRIi64 " periods)\n", scsi->callback_timer.period, scsi->temp_period); } static void spock_mca_write(int port, uint8_t val, void *priv) { - spock_t *scsi = (spock_t *)priv; + spock_t *scsi = (spock_t *) priv; - if (port < 0x102) - return; + if (port < 0x102) + return; - io_removehandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); - mem_mapping_disable(&scsi->bios_rom.mapping); + io_removehandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); + mem_mapping_disable(&scsi->bios_rom.mapping); - scsi->pos_regs[port & 7] = val; + scsi->pos_regs[port & 7] = val; - scsi->adapter_id = (scsi->pos_regs[3] & 0xe0) >> 5; + scsi->adapter_id = (scsi->pos_regs[3] & 0xe0) >> 5; - if (scsi->pos_regs[2] & 1) { - io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); - if ((scsi->pos_regs[2] >> 4) == 0x0f) - mem_mapping_disable(&scsi->bios_rom.mapping); - else { - mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); - } + if (scsi->pos_regs[2] & 1) { + io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); + if ((scsi->pos_regs[2] >> 4) == 0x0f) + mem_mapping_disable(&scsi->bios_rom.mapping); + else { + mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); } + } } static uint8_t spock_mca_read(int port, void *priv) { - spock_t *scsi = (spock_t *)priv; + spock_t *scsi = (spock_t *) priv; - return scsi->pos_regs[port & 7]; + return scsi->pos_regs[port & 7]; } static uint8_t spock_mca_feedb(void *priv) { - spock_t *scsi = (spock_t *)priv; + spock_t *scsi = (spock_t *) priv; - return (scsi->pos_regs[2] & 0x01); + return (scsi->pos_regs[2] & 0x01); } static void spock_mca_reset(void *priv) { - spock_t *scsi = (spock_t *)priv; - int i; + spock_t *scsi = (spock_t *) priv; + int i; - scsi->in_reset = 2; - scsi->cmd_timer = SPOCK_TIME * 50; - scsi->status = STATUS_BUSY; - scsi->scsi_state = SCSI_STATE_IDLE; - scsi->scb_state = 0; - scsi->in_invalid = 0; - scsi->attention_wait = 0; - scsi->basic_ctrl = 0; + scsi->in_reset = 2; + scsi->cmd_timer = SPOCK_TIME * 50; + scsi->status = STATUS_BUSY; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->scb_state = 0; + scsi->in_invalid = 0; + scsi->attention_wait = 0; + scsi->basic_ctrl = 0; - /* Reset all devices on controller reset. */ - for (i = 0; i < 8; i++) - scsi_device_reset(&scsi_devices[scsi->bus][i]); + /* Reset all devices on controller reset. */ + for (i = 0; i < 8; i++) + scsi_device_reset(&scsi_devices[scsi->bus][i]); - scsi->adapter_reset = 0; + scsi->adapter_reset = 0; } static void * spock_init(const device_t *info) { - int c; - spock_t *scsi = malloc(sizeof(spock_t)); - memset(scsi, 0x00, sizeof(spock_t)); + int c; + spock_t *scsi = malloc(sizeof(spock_t)); + memset(scsi, 0x00, sizeof(spock_t)); - scsi->bus = scsi_get_bus(); + scsi->bus = scsi_get_bus(); - scsi->irq = 14; + scsi->irq = 14; - scsi->bios_ver = device_get_config_int("bios_ver"); + scsi->bios_ver = device_get_config_int("bios_ver"); switch (scsi->bios_ver) { - case 1: + case 1: rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM, - 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); break; - case 0: + case 0: rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM, - 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); break; } mem_mapping_disable(&scsi->bios_rom.mapping); scsi->pos_regs[0] = 0xff; scsi->pos_regs[1] = 0x8e; - mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi); + mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi); - scsi->in_reset = 2; - scsi->cmd_timer = SPOCK_TIME * 50; - scsi->status = STATUS_BUSY; + scsi->in_reset = 2; + scsi->cmd_timer = SPOCK_TIME * 50; + scsi->status = STATUS_BUSY; - for (c = 0; c < (SCSI_ID_MAX-1); c++) { + for (c = 0; c < (SCSI_ID_MAX - 1); c++) { scsi->dev_id[c].phys_id = -1; } - scsi->dev_id[SCSI_ID_MAX-1].phys_id = scsi->adapter_id; + scsi->dev_id[SCSI_ID_MAX - 1].phys_id = scsi->adapter_id; - timer_add(&scsi->callback_timer, spock_callback, scsi, 1); - scsi->callback_timer.period = 10.0; - timer_set_delay_u64(&scsi->callback_timer, (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC))); + timer_add(&scsi->callback_timer, spock_callback, scsi, 1); + scsi->callback_timer.period = 10.0; + timer_set_delay_u64(&scsi->callback_timer, (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC))); - return scsi; + return scsi; } static void spock_close(void *p) { - spock_t *scsi = (spock_t *)p; + spock_t *scsi = (spock_t *) p; - if (scsi) { - free(scsi); - scsi = NULL; - } + if (scsi) { + free(scsi); + scsi = NULL; + } } static int spock_available(void) { - return rom_present(SPOCK_U68_1991_ROM) && rom_present(SPOCK_U69_1991_ROM) && - rom_present(SPOCK_U68_1990_ROM) && rom_present(SPOCK_U69_1990_ROM); + return rom_present(SPOCK_U68_1991_ROM) && rom_present(SPOCK_U69_1991_ROM) && rom_present(SPOCK_U68_1990_ROM) && rom_present(SPOCK_U69_1990_ROM); } static const device_config_t spock_rom_config[] = { -// clang-format off + // clang-format off { .name = "bios_ver", .description = "BIOS Version", @@ -1179,15 +1179,15 @@ static const device_config_t spock_rom_config[] = { }; const device_t spock_device = { - .name = "IBM PS/2 SCSI Adapter (Spock)", + .name = "IBM PS/2 SCSI Adapter (Spock)", .internal_name = "spock", - .flags = DEVICE_MCA, - .local = 0, - .init = spock_init, - .close = spock_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 0, + .init = spock_init, + .close = spock_close, + .reset = NULL, { .available = spock_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = spock_rom_config + .force_redraw = NULL, + .config = spock_rom_config }; diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 5cd1f6d8f..08b36585e 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -47,33 +47,28 @@ #include <86box/scsi_aha154x.h> #include <86box/scsi_x54x.h> +#define X54X_RESET_DURATION_US UINT64_C(50000) -#define X54X_RESET_DURATION_US UINT64_C(50000) - - -static void x54x_cmd_callback(void *priv); - +static void x54x_cmd_callback(void *priv); #ifdef ENABLE_X54X_LOG int x54x_do_log = ENABLE_X54X_LOG; - static void x54x_log(const char *fmt, ...) { va_list ap; if (x54x_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x54x_log(fmt, ...) +# define x54x_log(fmt, ...) #endif - static void x54x_irq(x54x_t *dev, int set) { @@ -81,178 +76,173 @@ x54x_irq(x54x_t *dev, int set) int irq; if (dev->ven_get_irq) - irq = dev->ven_get_irq(dev); - else - irq = dev->Irq; + irq = dev->ven_get_irq(dev); + else + irq = dev->Irq; if (dev->card_bus & DEVICE_PCI) { - x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot); + x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot); if (set) - pci_set_irq(dev->pci_slot, PCI_INTA); - else - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA); + else + pci_clear_irq(dev->pci_slot, PCI_INTA); } else { - x54x_log("%sing IRQ %i\n", set ? "Rais" : "Lower", irq); + x54x_log("%sing IRQ %i\n", set ? "Rais" : "Lower", irq); - if (set) { - if (dev->interrupt_type) - int_type = dev->interrupt_type(dev); + if (set) { + if (dev->interrupt_type) + int_type = dev->interrupt_type(dev); - if (int_type) - picintlevel(1 << irq); - else - picint(1 << irq); - } else - picintc(1 << irq); + if (int_type) + picintlevel(1 << irq); + else + picint(1 << irq); + } else + picintc(1 << irq); } } - static void raise_irq(x54x_t *dev, int suppress, uint8_t Interrupt) { if (Interrupt & (INTR_MBIF | INTR_MBOA)) { - x54x_log("%s: RaiseInterrupt(): Interrupt=%02X %s\n", - dev->name, Interrupt, (! (dev->Interrupt & INTR_HACC)) ? "Immediate" : "Pending"); - if (! (dev->Interrupt & INTR_HACC)) { - dev->Interrupt |= Interrupt; /* Report now. */ - } else { - dev->PendingInterrupt |= Interrupt; /* Report later. */ - } + x54x_log("%s: RaiseInterrupt(): Interrupt=%02X %s\n", + dev->name, Interrupt, (!(dev->Interrupt & INTR_HACC)) ? "Immediate" : "Pending"); + if (!(dev->Interrupt & INTR_HACC)) { + dev->Interrupt |= Interrupt; /* Report now. */ + } else { + dev->PendingInterrupt |= Interrupt; /* Report later. */ + } } else if (Interrupt & INTR_HACC) { - if (dev->Interrupt == 0 || dev->Interrupt == (INTR_ANY | INTR_HACC)) { - x54x_log("%s: RaiseInterrupt(): Interrupt=%02X\n", - dev->name, dev->Interrupt); - } - dev->Interrupt |= Interrupt; + if (dev->Interrupt == 0 || dev->Interrupt == (INTR_ANY | INTR_HACC)) { + x54x_log("%s: RaiseInterrupt(): Interrupt=%02X\n", + dev->name, dev->Interrupt); + } + dev->Interrupt |= Interrupt; } else { - x54x_log("%s: RaiseInterrupt(): Invalid interrupt state!\n", dev->name); + x54x_log("%s: RaiseInterrupt(): Invalid interrupt state!\n", dev->name); } dev->Interrupt |= INTR_ANY; if (dev->IrqEnabled && !suppress) - x54x_irq(dev, 1); + x54x_irq(dev, 1); } - static void clear_irq(x54x_t *dev) { dev->Interrupt = 0; x54x_log("%s: lowering IRQ %i (stat 0x%02x)\n", - dev->name, dev->Irq, dev->Interrupt); + dev->name, dev->Irq, dev->Interrupt); x54x_irq(dev, 0); if (dev->PendingInterrupt) { - x54x_log("%s: Raising Interrupt 0x%02X (Pending)\n", - dev->name, dev->Interrupt); - if (dev->MailboxOutInterrupts || !(dev->Interrupt & INTR_MBOA)) { - raise_irq(dev, 0, dev->PendingInterrupt); - } - dev->PendingInterrupt = 0; + x54x_log("%s: Raising Interrupt 0x%02X (Pending)\n", + dev->name, dev->Interrupt); + if (dev->MailboxOutInterrupts || !(dev->Interrupt & INTR_MBOA)) { + raise_irq(dev, 0, dev->PendingInterrupt); + } + dev->PendingInterrupt = 0; } } - static void target_check(x54x_t *dev, uint8_t id) { - if (! scsi_device_valid(&scsi_devices[dev->bus][id])) - fatal("BIOS INT13 device on ID %02i has disappeared\n", id); + if (!scsi_device_valid(&scsi_devices[dev->bus][id])) + fatal("BIOS INT13 device on ID %02i has disappeared\n", id); } - static uint8_t completion_code(uint8_t *sense) { uint8_t ret = 0xff; switch (sense[12]) { - case ASC_NONE: - ret = 0x00; - break; + case ASC_NONE: + ret = 0x00; + break; - case ASC_ILLEGAL_OPCODE: - case ASC_INV_FIELD_IN_CMD_PACKET: - case ASC_INV_FIELD_IN_PARAMETER_LIST: - case ASC_DATA_PHASE_ERROR: - ret = 0x01; - break; + case ASC_ILLEGAL_OPCODE: + case ASC_INV_FIELD_IN_CMD_PACKET: + case ASC_INV_FIELD_IN_PARAMETER_LIST: + case ASC_DATA_PHASE_ERROR: + ret = 0x01; + break; - case 0x12: - case ASC_LBA_OUT_OF_RANGE: - ret = 0x02; - break; + case 0x12: + case ASC_LBA_OUT_OF_RANGE: + ret = 0x02; + break; - case ASC_WRITE_PROTECTED: - ret = 0x03; - break; + case ASC_WRITE_PROTECTED: + ret = 0x03; + break; - case 0x14: - case 0x16: - ret = 0x04; - break; + case 0x14: + case 0x16: + ret = 0x04; + break; - case ASC_INCOMPATIBLE_FORMAT: - case ASC_ILLEGAL_MODE_FOR_THIS_TRACK: - ret = 0x0c; - break; + case ASC_INCOMPATIBLE_FORMAT: + case ASC_ILLEGAL_MODE_FOR_THIS_TRACK: + ret = 0x0c; + break; - case 0x10: - case 0x11: - ret = 0x10; - break; + case 0x10: + case 0x11: + ret = 0x10; + break; - case 0x17: - case 0x18: - ret = 0x11; - break; + case 0x17: + case 0x18: + ret = 0x11; + break; - case 0x01: - case 0x03: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - ret = 0x20; - break; + case 0x01: + case 0x03: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + ret = 0x20; + break; - case 0x15: - case 0x02: - ret = 0x40; - break; + case 0x15: + case 0x02: + ret = 0x40; + break; - case 0x25: - ret = 0x80; - break; + case 0x25: + ret = 0x80; + break; - case ASC_NOT_READY: - case ASC_MEDIUM_MAY_HAVE_CHANGED: - case 0x29: - case ASC_CAPACITY_DATA_CHANGED: - case ASC_MEDIUM_NOT_PRESENT: - ret = 0xaa; - break; + case ASC_NOT_READY: + case ASC_MEDIUM_MAY_HAVE_CHANGED: + case 0x29: + case ASC_CAPACITY_DATA_CHANGED: + case ASC_MEDIUM_NOT_PRESENT: + ret = 0xaa; + break; }; - return(ret); + return (ret); } - static uint8_t x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, uint32_t addr, int transfer_size) { @@ -261,25 +251,25 @@ x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, scsi_device_command_phase0(dev, cdb); if (dev->phase == SCSI_PHASE_STATUS) - return(completion_code(scsi_device_sense(dev))); + return (completion_code(scsi_device_sense(dev))); if (len > 0) { - if (dev->buffer_length == -1) { - fatal("Buffer length -1 when doing SCSI DMA\n"); - return(0xff); - } + if (dev->buffer_length == -1) { + fatal("Buffer length -1 when doing SCSI DMA\n"); + return (0xff); + } - if (dev->phase == SCSI_PHASE_DATA_IN) { - if (buf) - memcpy(buf, dev->sc->temp_buffer, dev->buffer_length); - else - dma_bm_write(addr, dev->sc->temp_buffer, dev->buffer_length, transfer_size); - } else if (dev->phase == SCSI_PHASE_DATA_OUT) { - if (buf) - memcpy(dev->sc->temp_buffer, buf, dev->buffer_length); - else - dma_bm_read(addr, dev->sc->temp_buffer, dev->buffer_length, transfer_size); - } + if (dev->phase == SCSI_PHASE_DATA_IN) { + if (buf) + memcpy(buf, dev->sc->temp_buffer, dev->buffer_length); + else + dma_bm_write(addr, dev->sc->temp_buffer, dev->buffer_length, transfer_size); + } else if (dev->phase == SCSI_PHASE_DATA_OUT) { + if (buf) + memcpy(dev->sc->temp_buffer, buf, dev->buffer_length); + else + dma_bm_read(addr, dev->sc->temp_buffer, dev->buffer_length, transfer_size); + } } scsi_device_command_phase1(dev); @@ -287,12 +277,11 @@ x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, return (completion_code(scsi_device_sense(dev))); } - static uint8_t x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf, int transfer_size) { uint8_t *cdb; - uint8_t ret; + uint8_t ret; cdb = (uint8_t *) malloc(12); memset(cdb, 0, 12); @@ -303,15 +292,14 @@ x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf, int transfer_size) free(cdb); - return(ret); + return (ret); } - static uint8_t x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf, int transfer_size) { uint8_t *cdb; - uint8_t ret; + uint8_t ret; cdb = (uint8_t *) malloc(12); memset(cdb, 0, 12); @@ -323,234 +311,231 @@ x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf, int transfer_size) free(cdb); - return(ret); + return (ret); } - static uint8_t x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer, int transfer_size) { uint8_t *rcbuf; - uint8_t ret; - int i; + uint8_t ret; + int i; memset(buffer, 0x00, 6); rcbuf = (uint8_t *) malloc(8); - ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size); + ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size); if (ret) { - free(rcbuf); - return(ret); - } + free(rcbuf); + return (ret); + } memset(buffer, 0x00, 6); - for (i=0; i<4; i++) - buffer[i] = rcbuf[i]; - for (i=4; i<6; i++) - buffer[i] = rcbuf[(i + 2) ^ 1]; + for (i = 0; i < 4; i++) + buffer[i] = rcbuf[i]; + for (i = 4; i < 6; i++) + buffer[i] = rcbuf[(i + 2) ^ 1]; x54x_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n", - buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); free(rcbuf); - return(0); + return (0); } - static int x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer, int transfer_size) { uint8_t *inqbuf, *rcbuf; - uint8_t ret; - int i; + uint8_t ret; + int i; memset(buffer, 0x00, 6); inqbuf = (uint8_t *) malloc(36); - ret = x54x_bios_inquiry(sd, inqbuf, transfer_size); + ret = x54x_bios_inquiry(sd, inqbuf, transfer_size); if (ret) { - free(inqbuf); - return(ret); + free(inqbuf); + return (ret); } buffer[4] = inqbuf[0]; buffer[5] = inqbuf[1]; rcbuf = (uint8_t *) malloc(8); - ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size); + ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size); if (ret) { - free(rcbuf); - free(inqbuf); - return(ret); - } + free(rcbuf); + free(inqbuf); + return (ret); + } for (i = 0; i < 4; i++) - buffer[i] = rcbuf[i]; + buffer[i] = rcbuf[i]; x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", - buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); free(rcbuf); free(inqbuf); - return(0); + return (0); } - /* This returns the completion code. */ static uint8_t x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) { - const int bios_cmd_to_scsi[18] = { 0, 0, GPCMD_READ_10, GPCMD_WRITE_10, GPCMD_VERIFY_10, 0, 0, - GPCMD_FORMAT_UNIT, 0, 0, 0, 0, GPCMD_SEEK_10, 0, 0, 0, - GPCMD_TEST_UNIT_READY, GPCMD_REZERO_UNIT }; - uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t *buf; - scsi_device_t *dev = NULL; - uint32_t dma_address = 0; - uint32_t lba; - int sector_len = cmd->secount; - uint8_t ret = 0x00; + const int bios_cmd_to_scsi[18] = { 0, 0, GPCMD_READ_10, GPCMD_WRITE_10, GPCMD_VERIFY_10, 0, 0, + GPCMD_FORMAT_UNIT, 0, 0, 0, 0, GPCMD_SEEK_10, 0, 0, 0, + GPCMD_TEST_UNIT_READY, GPCMD_REZERO_UNIT }; + uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t *buf; + scsi_device_t *dev = NULL; + uint32_t dma_address = 0; + uint32_t lba; + int sector_len = cmd->secount; + uint8_t ret = 0x00; if (islba) - lba = lba32_blk(cmd); - else - lba = (cmd->u.chs.cyl << 9) + (cmd->u.chs.head << 5) + cmd->u.chs.sec; + lba = lba32_blk(cmd); + else + lba = (cmd->u.chs.cyl << 9) + (cmd->u.chs.head << 5) + cmd->u.chs.sec; x54x_log("BIOS Command = 0x%02X\n", cmd->command); if (cmd->id > max_id) { - x54x_log("BIOS Target ID %i or LUN %i are above maximum\n", - cmd->id, cmd->lun); - ret = 0x80; + x54x_log("BIOS Target ID %i or LUN %i are above maximum\n", + cmd->id, cmd->lun); + ret = 0x80; } if (cmd->lun) { - x54x_log("BIOS Target LUN is not 0\n"); - ret = 0x80; + x54x_log("BIOS Target LUN is not 0\n"); + ret = 0x80; } if (!ret) { - /* Get pointer to selected device. */ - dev = &scsi_devices[x54x->bus][cmd->id]; - dev->buffer_length = 0; + /* Get pointer to selected device. */ + dev = &scsi_devices[x54x->bus][cmd->id]; + dev->buffer_length = 0; - if (! scsi_device_present(dev)) { - x54x_log("BIOS Target ID %i has no device attached\n", cmd->id); - ret = 0x80; - } else { - scsi_device_identify(dev, 0xff); + if (!scsi_device_present(dev)) { + x54x_log("BIOS Target ID %i has no device attached\n", cmd->id); + ret = 0x80; + } else { + scsi_device_identify(dev, 0xff); - if ((dev->type == SCSI_REMOVABLE_CDROM) && !(x54x->flags & X54X_CDROM_BOOT)) { - x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id); - return(0x80); - } else { - dma_address = ADDR_TO_U32(cmd->dma_address); + if ((dev->type == SCSI_REMOVABLE_CDROM) && !(x54x->flags & X54X_CDROM_BOOT)) { + x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id); + return (0x80); + } else { + dma_address = ADDR_TO_U32(cmd->dma_address); - x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", - sector_len, dma_address); - } - } + x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", + sector_len, dma_address); + } + } } - if (!ret) switch(cmd->command) { - case 0x00: /* Reset Disk System, in practice it's a nop */ - ret = 0x00; - break; + if (!ret) + switch (cmd->command) { + case 0x00: /* Reset Disk System, in practice it's a nop */ + ret = 0x00; + break; - case 0x01: /* Read Status of Last Operation */ - target_check(x54x, cmd->id); + case 0x01: /* Read Status of Last Operation */ + target_check(x54x, cmd->id); - /* - * Assuming 14 bytes because that is the default - * length for SCSI sense, and no command-specific - * indication is given. - */ - if (sector_len > 0) { - x54x_log("BIOS DMA: Reading 14 bytes at %08X\n", - dma_address); - dma_bm_write(dma_address, scsi_device_sense(dev), 14, x54x->transfer_size); - } + /* + * Assuming 14 bytes because that is the default + * length for SCSI sense, and no command-specific + * indication is given. + */ + if (sector_len > 0) { + x54x_log("BIOS DMA: Reading 14 bytes at %08X\n", + dma_address); + dma_bm_write(dma_address, scsi_device_sense(dev), 14, x54x->transfer_size); + } - return(0); - break; + return (0); + break; - case 0x02: /* Read Desired Sectors to Memory */ - case 0x03: /* Write Desired Sectors from Memory */ - case 0x04: /* Verify Desired Sectors */ - case 0x0c: /* Seek */ - target_check(x54x, cmd->id); + case 0x02: /* Read Desired Sectors to Memory */ + case 0x03: /* Write Desired Sectors from Memory */ + case 0x04: /* Verify Desired Sectors */ + case 0x0c: /* Seek */ + target_check(x54x, cmd->id); - cdb[0] = bios_cmd_to_scsi[cmd->command]; - cdb[1] = (cmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - if (cmd->command != 0x0c) - cdb[8] = sector_len; + cdb[0] = bios_cmd_to_scsi[cmd->command]; + cdb[1] = (cmd->lun & 7) << 5; + cdb[2] = (lba >> 24) & 0xff; + cdb[3] = (lba >> 16) & 0xff; + cdb[4] = (lba >> 8) & 0xff; + cdb[5] = lba & 0xff; + if (cmd->command != 0x0c) + cdb[8] = sector_len; - ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address, x54x->transfer_size); - if (cmd->command == 0x0c) - ret = !!ret; - break; + ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address, x54x->transfer_size); + if (cmd->command == 0x0c) + ret = !!ret; + break; - default: - x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command); - case 0x05: /* Format Track, invalid since SCSI has no tracks */ - case 0x0a: /* ???? */ - case 0x0b: /* ???? */ - case 0x12: /* ???? */ - case 0x13: /* ???? */ -//FIXME: add a longer delay here --FvK - ret = 0x01; - break; + default: + x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command); + case 0x05: /* Format Track, invalid since SCSI has no tracks */ + case 0x0a: /* ???? */ + case 0x0b: /* ???? */ + case 0x12: /* ???? */ + case 0x13: /* ???? */ + // FIXME: add a longer delay here --FvK + ret = 0x01; + break; - case 0x06: /* Identify SCSI Devices, in practice it's a nop */ - case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */ - case 0x0d: /* Alternate Disk Reset, in practice it's a nop */ - case 0x0e: /* Read Sector Buffer */ - case 0x0f: /* Write Sector Buffer */ - case 0x14: /* Controller Diagnostic */ -//FIXME: add a longer delay here --FvK - ret = 0x00; - break; + case 0x06: /* Identify SCSI Devices, in practice it's a nop */ + case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */ + case 0x0d: /* Alternate Disk Reset, in practice it's a nop */ + case 0x0e: /* Read Sector Buffer */ + case 0x0f: /* Write Sector Buffer */ + case 0x14: /* Controller Diagnostic */ + // FIXME: add a longer delay here --FvK + ret = 0x00; + break; - case 0x07: /* Format Unit */ - case 0x10: /* Test Drive Ready */ - case 0x11: /* Recalibrate */ - target_check(x54x, cmd->id); + case 0x07: /* Format Unit */ + case 0x10: /* Test Drive Ready */ + case 0x11: /* Recalibrate */ + target_check(x54x, cmd->id); - cdb[0] = bios_cmd_to_scsi[cmd->command]; - cdb[1] = (cmd->lun & 7) << 5; + cdb[0] = bios_cmd_to_scsi[cmd->command]; + cdb[1] = (cmd->lun & 7) << 5; - ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address, x54x->transfer_size); - break; + ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address, x54x->transfer_size); + break; - case 0x08: /* Read Drive Parameters */ - case 0x15: /* Read DASD Type */ - target_check(x54x, cmd->id); + case 0x08: /* Read Drive Parameters */ + case 0x15: /* Read DASD Type */ + target_check(x54x, cmd->id); - dev->buffer_length = 6; + dev->buffer_length = 6; - buf = (uint8_t *) malloc(6); - if (cmd->command == 0x08) - ret = x54x_bios_command_08(dev, buf, x54x->transfer_size); - else - ret = x54x_bios_command_15(dev, buf, x54x->transfer_size); + buf = (uint8_t *) malloc(6); + if (cmd->command == 0x08) + ret = x54x_bios_command_08(dev, buf, x54x->transfer_size); + else + ret = x54x_bios_command_15(dev, buf, x54x->transfer_size); - x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); - dma_bm_write(dma_address, buf, 4, x54x->transfer_size); - free(buf); + x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); + dma_bm_write(dma_address, buf, 4, x54x->transfer_size); + free(buf); - break; - } + break; + } x54x_log("BIOS Request %02X complete: %02X\n", cmd->command, ret); - return(ret); + return (ret); } - static void x54x_cmd_done(x54x_t *dev, int suppress) { @@ -560,49 +545,46 @@ x54x_cmd_done(x54x_t *dev, int suppress) dev->Status |= STAT_IDLE; if (dev->ven_cmd_is_fast) { - fast = dev->ven_cmd_is_fast(dev); + fast = dev->ven_cmd_is_fast(dev); } if ((dev->Command != CMD_START_SCSI) || fast) { - dev->Status &= ~STAT_DFULL; - x54x_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); - raise_irq(dev, suppress, INTR_HACC); + dev->Status &= ~STAT_DFULL; + x54x_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); + raise_irq(dev, suppress, INTR_HACC); } - dev->Command = 0xff; + dev->Command = 0xff; dev->CmdParam = 0; } - static void x54x_add_to_period(x54x_t *dev, int TransferLength) { dev->temp_period += (uint64_t) TransferLength; } - static void x54x_mbi_setup(x54x_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, - uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc) + uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc) { Req_t *req = &dev->Req; req->CCBPointer = CCBPointer; memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); - req->Is24bit = !!(dev->flags & X54X_MBX_24BIT); - req->HostStatus = HostStatus; - req->TargetStatus = TargetStatus; + req->Is24bit = !!(dev->flags & X54X_MBX_24BIT); + req->HostStatus = HostStatus; + req->TargetStatus = TargetStatus; req->MailboxCompletionCode = mbcc; x54x_log("Mailbox in setup\n"); } - static void x54x_ccb(x54x_t *dev) { - Req_t *req = &dev->Req; - uint8_t bytes[4] = { 0, 0, 0, 0}; + Req_t *req = &dev->Req; + uint8_t bytes[4] = { 0, 0, 0, 0 }; /* Rewrite the CCB up to the CDB. */ x54x_log("CCB completion code and statuses rewritten (pointer %08X)\n", req->CCBPointer); @@ -614,341 +596,325 @@ x54x_ccb(x54x_t *dev) x54x_add_to_period(dev, 3); if (dev->MailboxOutInterrupts) - dev->ToRaise = INTR_MBOA | INTR_ANY; - else - dev->ToRaise = 0; + dev->ToRaise = INTR_MBOA | INTR_ANY; + else + dev->ToRaise = 0; } - static void x54x_mbi(x54x_t *dev) { Req_t *req = &dev->Req; -// uint32_t CCBPointer = req->CCBPointer; - addr24 CCBPointer; - CCBU *CmdBlock = &(req->CmdBlock); - uint8_t HostStatus = req->HostStatus; - uint8_t TargetStatus = req->TargetStatus; + // uint32_t CCBPointer = req->CCBPointer; + addr24 CCBPointer; + CCBU *CmdBlock = &(req->CmdBlock); + uint8_t HostStatus = req->HostStatus; + uint8_t TargetStatus = req->TargetStatus; uint32_t MailboxCompletionCode = req->MailboxCompletionCode; uint32_t Incoming; - uint8_t bytes[4] = { 0, 0, 0, 0 }; + uint8_t bytes[4] = { 0, 0, 0, 0 }; Incoming = dev->MailboxInAddr + (dev->MailboxInPosCur * ((dev->flags & X54X_MBX_24BIT) ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); if (MailboxCompletionCode != MBI_NOT_FOUND) { - CmdBlock->common.HostStatus = HostStatus; - CmdBlock->common.TargetStatus = TargetStatus; + CmdBlock->common.HostStatus = HostStatus; + CmdBlock->common.TargetStatus = TargetStatus; - /* Rewrite the CCB up to the CDB. */ - x54x_log("CCB statuses rewritten (pointer %08X)\n", req->CCBPointer); - dma_bm_read(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size); - bytes[2] = req->HostStatus; - bytes[3] = req->TargetStatus; - dma_bm_write(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size); - x54x_add_to_period(dev, 2); + /* Rewrite the CCB up to the CDB. */ + x54x_log("CCB statuses rewritten (pointer %08X)\n", req->CCBPointer); + dma_bm_read(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size); + bytes[2] = req->HostStatus; + bytes[3] = req->TargetStatus; + dma_bm_write(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size); + x54x_add_to_period(dev, 2); } else { - x54x_log("Mailbox not found!\n"); + x54x_log("Mailbox not found!\n"); } - x54x_log("Host Status 0x%02X, Target Status 0x%02X\n",HostStatus,TargetStatus); + x54x_log("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); if (dev->flags & X54X_MBX_24BIT) { - U32_TO_ADDR(CCBPointer, req->CCBPointer); - x54x_log("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); - bytes[0] = req->MailboxCompletionCode; - memcpy(&(bytes[1]), (uint8_t *)&CCBPointer, 3); - dma_bm_write(Incoming, (uint8_t *) bytes, 4, dev->transfer_size); - x54x_add_to_period(dev, 4); - x54x_log("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); + U32_TO_ADDR(CCBPointer, req->CCBPointer); + x54x_log("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); + bytes[0] = req->MailboxCompletionCode; + memcpy(&(bytes[1]), (uint8_t *) &CCBPointer, 3); + dma_bm_write(Incoming, (uint8_t *) bytes, 4, dev->transfer_size); + x54x_add_to_period(dev, 4); + x54x_log("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); } else { - x54x_log("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); - dma_bm_write(Incoming, (uint8_t *)&(req->CCBPointer), 4, dev->transfer_size); - dma_bm_read(Incoming + 4, (uint8_t *) bytes, 4, dev->transfer_size); - bytes[0] = req->HostStatus; - bytes[1] = req->TargetStatus; - bytes[3] = req->MailboxCompletionCode; - dma_bm_write(Incoming + 4, (uint8_t *) bytes, 4, dev->transfer_size); - x54x_add_to_period(dev, 7); - x54x_log("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + x54x_log("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); + dma_bm_write(Incoming, (uint8_t *) &(req->CCBPointer), 4, dev->transfer_size); + dma_bm_read(Incoming + 4, (uint8_t *) bytes, 4, dev->transfer_size); + bytes[0] = req->HostStatus; + bytes[1] = req->TargetStatus; + bytes[3] = req->MailboxCompletionCode; + dma_bm_write(Incoming + 4, (uint8_t *) bytes, 4, dev->transfer_size); + x54x_add_to_period(dev, 7); + x54x_log("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); } dev->MailboxInPosCur++; if (dev->MailboxInPosCur >= dev->MailboxCount) - dev->MailboxInPosCur = 0; + dev->MailboxInPosCur = 0; dev->ToRaise = INTR_MBIF | INTR_ANY; if (dev->MailboxOutInterrupts) - dev->ToRaise |= INTR_MBOA; + dev->ToRaise |= INTR_MBOA; } - static void x54x_rd_sge(x54x_t *dev, int Is24bit, uint32_t Address, SGE32 *SG) { - SGE SGE24; + SGE SGE24; uint8_t bytes[8]; if (Is24bit) { - if (dev->transfer_size == 4) { - /* 32-bit device, do this to make the transfer divisible by 4 bytes. */ - dma_bm_read(Address, (uint8_t *) bytes, 8, dev->transfer_size); - memcpy((uint8_t *)&SGE24, bytes, sizeof(SGE)); - } else { - /* 16-bit device, special handling not needed. */ - dma_bm_read(Address, (uint8_t *)&SGE24, 8, dev->transfer_size); - } - x54x_add_to_period(dev, sizeof(SGE)); + if (dev->transfer_size == 4) { + /* 32-bit device, do this to make the transfer divisible by 4 bytes. */ + dma_bm_read(Address, (uint8_t *) bytes, 8, dev->transfer_size); + memcpy((uint8_t *) &SGE24, bytes, sizeof(SGE)); + } else { + /* 16-bit device, special handling not needed. */ + dma_bm_read(Address, (uint8_t *) &SGE24, 8, dev->transfer_size); + } + x54x_add_to_period(dev, sizeof(SGE)); - /* Convert the 24-bit entries into 32-bit entries. */ - x54x_log("Read S/G block: %06X, %06X\n", SGE24.Segment, SGE24.SegmentPointer); - SG->Segment = ADDR_TO_U32(SGE24.Segment); - SG->SegmentPointer = ADDR_TO_U32(SGE24.SegmentPointer); + /* Convert the 24-bit entries into 32-bit entries. */ + x54x_log("Read S/G block: %06X, %06X\n", SGE24.Segment, SGE24.SegmentPointer); + SG->Segment = ADDR_TO_U32(SGE24.Segment); + SG->SegmentPointer = ADDR_TO_U32(SGE24.SegmentPointer); } else { - dma_bm_read(Address, (uint8_t *)SG, sizeof(SGE32), dev->transfer_size); - x54x_add_to_period(dev, sizeof(SGE32)); + dma_bm_read(Address, (uint8_t *) SG, sizeof(SGE32), dev->transfer_size); + x54x_add_to_period(dev, sizeof(SGE32)); } } - static int x54x_get_length(x54x_t *dev, Req_t *req, int Is24bit) { uint32_t DataPointer, DataLength; uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); - SGE32 SGBuffer; + SGE32 SGBuffer; uint32_t DataToTransfer = 0, i = 0; if (Is24bit) { - DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); - DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); - x54x_log("Data length: %08X\n", req->CmdBlock.old.DataLength); + DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + x54x_log("Data length: %08X\n", req->CmdBlock.old.DataLength); } else { - DataPointer = req->CmdBlock.new.DataPointer; - DataLength = req->CmdBlock.new.DataLength; + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; } x54x_log("Data Buffer write: length %d, pointer 0x%04X\n", - DataLength, DataPointer); + DataLength, DataPointer); if (!DataLength) - return(0); + return (0); if (req->CmdBlock.common.ControlByte != 0x03) { - if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || - req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { - for (i = 0; i < DataLength; i += SGEntryLength) { - x54x_rd_sge(dev, Is24bit, DataPointer + i, &SGBuffer); + if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { + for (i = 0; i < DataLength; i += SGEntryLength) { + x54x_rd_sge(dev, Is24bit, DataPointer + i, &SGBuffer); - DataToTransfer += SGBuffer.Segment; - } - return(DataToTransfer); - } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || - req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { - return(DataLength); - } else { - return(0); - } + DataToTransfer += SGBuffer.Segment; + } + return (DataToTransfer); + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + return (DataLength); + } else { + return (0); + } } else { - return(0); + return (0); } } - static void x54x_set_residue(x54x_t *dev, Req_t *req, int32_t TransferLength) { uint32_t Residue = 0; - addr24 Residue24; - int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length; - uint8_t bytes[4] = { 0, 0, 0, 0 }; + addr24 Residue24; + int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length; + uint8_t bytes[4] = { 0, 0, 0, 0 }; - if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || - (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { - if ((TransferLength > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - TransferLength -= BufLen; - if (TransferLength > 0) - Residue = TransferLength; - } + if ((TransferLength > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { + TransferLength -= BufLen; + if (TransferLength > 0) + Residue = TransferLength; + } - if (req->Is24bit) { - U32_TO_ADDR(Residue24, Residue); - dma_bm_read(req->CCBPointer + 0x0004, (uint8_t *) bytes, 4, dev->transfer_size); - memcpy((uint8_t *) bytes, (uint8_t *)&Residue24, 3); - dma_bm_write(req->CCBPointer + 0x0004, (uint8_t *) bytes, 4, dev->transfer_size); - x54x_add_to_period(dev, 3); - x54x_log("24-bit Residual data length for reading: %d\n", Residue); - } else { - dma_bm_write(req->CCBPointer + 0x0004, (uint8_t *)&Residue, 4, dev->transfer_size); - x54x_add_to_period(dev, 4); - x54x_log("32-bit Residual data length for reading: %d\n", Residue); - } + if (req->Is24bit) { + U32_TO_ADDR(Residue24, Residue); + dma_bm_read(req->CCBPointer + 0x0004, (uint8_t *) bytes, 4, dev->transfer_size); + memcpy((uint8_t *) bytes, (uint8_t *) &Residue24, 3); + dma_bm_write(req->CCBPointer + 0x0004, (uint8_t *) bytes, 4, dev->transfer_size); + x54x_add_to_period(dev, 3); + x54x_log("24-bit Residual data length for reading: %d\n", Residue); + } else { + dma_bm_write(req->CCBPointer + 0x0004, (uint8_t *) &Residue, 4, dev->transfer_size); + x54x_add_to_period(dev, 4); + x54x_log("32-bit Residual data length for reading: %d\n", Residue); + } } } - static void x54x_buf_dma_transfer(x54x_t *dev, 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 = scsi_devices[dev->bus][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; - SGE32 SGBuffer; + int32_t BufLen = scsi_devices[dev->bus][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; + SGE32 SGBuffer; uint32_t DataToTransfer = 0; if (Is24bit) { - DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); - DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); } else { - DataPointer = req->CmdBlock.new.DataPointer; - DataLength = req->CmdBlock.new.DataLength; + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; } x54x_log("Data Buffer %s: length %d (%u), pointer 0x%04X\n", - dir ? "write" : "read", BufLen, DataLength, DataPointer); + dir ? "write" : "read", BufLen, DataLength, DataPointer); if ((req->CmdBlock.common.ControlByte != 0x03) && TransferLength && BufLen) { - if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || - (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { - /* 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 no read/write commands. */ - if ((DataLength > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - for (i = 0; i < DataLength; i += SGEntryLength) { - x54x_rd_sge(dev, Is24bit, DataPointer + i, &SGBuffer); + /* 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 no read/write commands. */ + if ((DataLength > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { + for (i = 0; i < DataLength; i += SGEntryLength) { + x54x_rd_sge(dev, Is24bit, DataPointer + i, &SGBuffer); - Address = SGBuffer.SegmentPointer; - DataToTransfer = MIN((int) SGBuffer.Segment, BufLen); + Address = SGBuffer.SegmentPointer; + DataToTransfer = MIN((int) SGBuffer.Segment, BufLen); - if (read_from_host && DataToTransfer) { - x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - dma_bm_read(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size); - } - else if (write_to_host && DataToTransfer) { - x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - dma_bm_write(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size); - } - else - x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); + if (read_from_host && DataToTransfer) { + x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); + dma_bm_read(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size); + } else if (write_to_host && DataToTransfer) { + x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); + dma_bm_write(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size); + } else + x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - sg_pos += SGBuffer.Segment; + sg_pos += SGBuffer.Segment; - BufLen -= SGBuffer.Segment; - if (BufLen < 0) - BufLen = 0; + BufLen -= SGBuffer.Segment; + if (BufLen < 0) + BufLen = 0; - x54x_log("After S/G segment done: %i, %i\n", sg_pos, BufLen); - } - } - } else if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND) || - (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)) { - Address = DataPointer; + x54x_log("After S/G segment done: %i, %i\n", sg_pos, BufLen); + } + } + } else if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND) || (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)) { + Address = DataPointer; - if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - if (read_from_host) - dma_bm_read(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size); - else if (write_to_host) - dma_bm_write(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size); - } - } + if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { + if (read_from_host) + dma_bm_read(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size); + else if (write_to_host) + dma_bm_write(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size); + } + } } } - static uint8_t ConvertSenseLength(uint8_t RequestSenseLength) { x54x_log("Unconverted Request Sense length %i\n", RequestSenseLength); if (RequestSenseLength == 0) - RequestSenseLength = 14; + RequestSenseLength = 14; else if (RequestSenseLength == 1) - RequestSenseLength = 0; + RequestSenseLength = 0; x54x_log("Request Sense length %i\n", RequestSenseLength); - return(RequestSenseLength); + return (RequestSenseLength); } - uint32_t SenseBufferPointer(Req_t *req) { uint32_t SenseBufferAddress; if (req->Is24bit) { - SenseBufferAddress = req->CCBPointer; - SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; + SenseBufferAddress = req->CCBPointer; + SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; } else { - SenseBufferAddress = req->CmdBlock.new.SensePointer; + SenseBufferAddress = req->CmdBlock.new.SensePointer; } - return(SenseBufferAddress); + return (SenseBufferAddress); } - static void SenseBufferFree(x54x_t *dev, Req_t *req, int Copy) { - uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); + uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); uint32_t SenseBufferAddress; - uint8_t temp_sense[256]; + uint8_t temp_sense[256]; if (SenseLength && Copy) { scsi_device_request_sense(&scsi_devices[dev->bus][req->TargetID], temp_sense, SenseLength); - /* - * The sense address, in 32-bit mode, is located in the - * Sense Pointer of the CCB, but in 24-bit mode, it is - * located at the end of the Command Descriptor Block. - */ - SenseBufferAddress = SenseBufferPointer(req); + /* + * The sense address, in 32-bit mode, is located in the + * Sense Pointer of the CCB, but in 24-bit mode, it is + * located at the end of the Command Descriptor Block. + */ + SenseBufferAddress = SenseBufferPointer(req); - x54x_log("Request Sense address: %02X\n", SenseBufferAddress); + x54x_log("Request Sense address: %02X\n", SenseBufferAddress); - x54x_log("SenseBufferFree(): Writing %i bytes at %08X\n", - SenseLength, SenseBufferAddress); - dma_bm_write(SenseBufferAddress, temp_sense, SenseLength, dev->transfer_size); - x54x_add_to_period(dev, SenseLength); - x54x_log("Sense data written to buffer: %02X %02X %02X\n", - temp_sense[2], temp_sense[12], temp_sense[13]); + x54x_log("SenseBufferFree(): Writing %i bytes at %08X\n", + SenseLength, SenseBufferAddress); + dma_bm_write(SenseBufferAddress, temp_sense, SenseLength, dev->transfer_size); + x54x_add_to_period(dev, SenseLength); + x54x_log("Sense data written to buffer: %02X %02X %02X\n", + temp_sense[2], temp_sense[12], temp_sense[13]); } } - static void x54x_scsi_cmd(x54x_t *dev) { - Req_t *req = &dev->Req; - uint8_t bit24 = !!req->Is24bit; - uint32_t i, target_cdb_len = 12; + Req_t *req = &dev->Req; + uint8_t bit24 = !!req->Is24bit; + uint32_t i, target_cdb_len = 12; scsi_device_t *sd; sd = &scsi_devices[dev->bus][req->TargetID]; - target_cdb_len = 12; + target_cdb_len = 12; dev->target_data_len = x54x_get_length(dev, req, bit24); if (!scsi_device_valid(sd)) - fatal("SCSI target on %02i has disappeared\n", req->TargetID); + fatal("SCSI target on %02i has disappeared\n", req->TargetID); x54x_log("dev->target_data_len = %i\n", dev->target_data_len); x54x_log("SCSI command being executed on ID %i, LUN %i\n", req->TargetID, req->LUN); x54x_log("SCSI CDB[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); - for (i=1; iCmdBlock.common.CdbLength; i++) - x54x_log("SCSI CDB[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) + x54x_log("SCSI CDB[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); memset(dev->temp_cdb, 0x00, target_cdb_len); if (req->CmdBlock.common.CdbLength <= target_cdb_len) { - memcpy(dev->temp_cdb, req->CmdBlock.common.Cdb, - req->CmdBlock.common.CdbLength); - x54x_add_to_period(dev, req->CmdBlock.common.CdbLength); + memcpy(dev->temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + x54x_add_to_period(dev, req->CmdBlock.common.CdbLength); } else { - memcpy(dev->temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len); - x54x_add_to_period(dev, target_cdb_len); + memcpy(dev->temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len); + x54x_add_to_period(dev, target_cdb_len); } dev->Residue = 0; @@ -961,86 +927,83 @@ x54x_scsi_cmd(x54x_t *dev) x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03)); if (dev->scsi_cmd_phase == SCSI_PHASE_STATUS) - dev->callback_sub_phase = 3; + dev->callback_sub_phase = 3; else - dev->callback_sub_phase = 2; + dev->callback_sub_phase = 2; x54x_log("scsi_devices[%02i][%02i].Status = %02X\n", dev->bus, req->TargetID, sd->status); } - static void x54x_scsi_cmd_phase1(x54x_t *dev) { - Req_t *req = &dev->Req; - double p; - uint8_t bit24 = !!req->Is24bit; + Req_t *req = &dev->Req; + double p; + uint8_t bit24 = !!req->Is24bit; scsi_device_t *sd; sd = &scsi_devices[dev->bus][req->TargetID]; if (dev->scsi_cmd_phase != SCSI_PHASE_STATUS) { - if ((dev->temp_cdb[0] != 0x03) || (req->CmdBlock.common.ControlByte != 0x03)) { - p = scsi_device_get_callback(sd); - if (p <= 0.0) - x54x_add_to_period(dev, sd->buffer_length); - else - dev->media_period += p; - x54x_buf_dma_transfer(dev, req, bit24, dev->target_data_len, (dev->scsi_cmd_phase == SCSI_PHASE_DATA_OUT)); - scsi_device_command_phase1(sd); - } + if ((dev->temp_cdb[0] != 0x03) || (req->CmdBlock.common.ControlByte != 0x03)) { + p = scsi_device_get_callback(sd); + if (p <= 0.0) + x54x_add_to_period(dev, sd->buffer_length); + else + dev->media_period += p; + x54x_buf_dma_transfer(dev, req, bit24, dev->target_data_len, (dev->scsi_cmd_phase == SCSI_PHASE_DATA_OUT)); + scsi_device_command_phase1(sd); + } } dev->callback_sub_phase = 3; x54x_log("scsi_devices[%02xi][%02i].Status = %02X\n", x54x->bus, req->TargetID, sd->status); } - static void x54x_request_sense(x54x_t *dev) { - Req_t *req = &dev->Req; - uint32_t SenseBufferAddress; + Req_t *req = &dev->Req; + uint32_t SenseBufferAddress; scsi_device_t *sd; sd = &scsi_devices[dev->bus][req->TargetID]; if (dev->scsi_cmd_phase != SCSI_PHASE_STATUS) { - if ((dev->temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) { - /* Request sense in non-data mode - sense goes to sense buffer. */ - sd->buffer_length = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); - if ((sd->status != SCSI_STATUS_OK) && (sd->buffer_length > 0)) { - SenseBufferAddress = SenseBufferPointer(req); - dma_bm_write(SenseBufferAddress, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size); - x54x_add_to_period(dev, sd->buffer_length); - } - scsi_device_command_phase1(sd); - } else - SenseBufferFree(dev, req, (sd->status != SCSI_STATUS_OK)); + if ((dev->temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) { + /* Request sense in non-data mode - sense goes to sense buffer. */ + sd->buffer_length = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); + if ((sd->status != SCSI_STATUS_OK) && (sd->buffer_length > 0)) { + SenseBufferAddress = SenseBufferPointer(req); + dma_bm_write(SenseBufferAddress, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size); + x54x_add_to_period(dev, sd->buffer_length); + } + scsi_device_command_phase1(sd); + } else + SenseBufferFree(dev, req, (sd->status != SCSI_STATUS_OK)); } else - SenseBufferFree(dev, req, (sd->status != SCSI_STATUS_OK)); + SenseBufferFree(dev, req, (sd->status != SCSI_STATUS_OK)); x54x_set_residue(dev, req, dev->target_data_len); x54x_log("Request complete\n"); if (sd->status == SCSI_STATUS_OK) { - x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); } 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_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); } dev->callback_sub_phase = 4; x54x_log("scsi_devices[%02i][%02i].Status = %02X\n", dev->bus, req->TargetID, sd->status); } - static void x54x_mbo_free(x54x_t *dev) { - uint8_t CmdStatus = MBO_FREE; + uint8_t CmdStatus = MBO_FREE; uint32_t CodeOffset = 0; CodeOffset = (dev->flags & X54X_MBX_24BIT) ? 0 : 7; @@ -1049,11 +1012,10 @@ x54x_mbo_free(x54x_t *dev) dma_bm_write(dev->Outgoing + CodeOffset, &CmdStatus, 1, dev->transfer_size); } - static void x54x_notify(x54x_t *dev) { - Req_t *req = &dev->Req; + Req_t *req = &dev->Req; scsi_device_t *sd; sd = &scsi_devices[dev->bus][req->TargetID]; @@ -1061,41 +1023,40 @@ x54x_notify(x54x_t *dev) x54x_mbo_free(dev); if (dev->MailboxIsBIOS) - x54x_ccb(dev); + x54x_ccb(dev); else - x54x_mbi(dev); + x54x_mbi(dev); /* Make sure to restore device to non-IDENTIFY'd state as we disconnect. */ if (sd->type != SCSI_NONE) - scsi_device_identify(sd, SCSI_LUN_USE_CDB); + scsi_device_identify(sd, SCSI_LUN_USE_CDB); } - static void x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) { - Req_t *req = &dev->Req; - uint8_t id, lun; + Req_t *req = &dev->Req; + uint8_t id, lun; scsi_device_t *sd; /* Fetch data from the Command Control Block. */ - dma_bm_read(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32), dev->transfer_size); + dma_bm_read(CCBPointer, (uint8_t *) &req->CmdBlock, sizeof(CCB32), dev->transfer_size); x54x_add_to_period(dev, sizeof(CCB32)); - req->Is24bit = !!(dev->flags & X54X_MBX_24BIT); + req->Is24bit = !!(dev->flags & X54X_MBX_24BIT); req->CCBPointer = CCBPointer; - req->TargetID = req->Is24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; - req->LUN = req->Is24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; + req->TargetID = req->Is24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; + req->LUN = req->Is24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; - id = req->TargetID; - sd = &scsi_devices[dev->bus][id]; + id = req->TargetID; + sd = &scsi_devices[dev->bus][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); - x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, - CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); - dev->callback_sub_phase = 4; - return; + x54x_log("SCSI Target ID %i or LUN %i is not valid\n", id, lun); + x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); + dev->callback_sub_phase = 4; + return; } x54x_log("Scanning SCSI Target ID %i\n", id); @@ -1103,121 +1064,117 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) sd->status = SCSI_STATUS_OK; if (!scsi_device_present(sd) || (lun > 0)) { - 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); - dev->callback_sub_phase = 4; + 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); + dev->callback_sub_phase = 4; } else { - x54x_log("SCSI Target ID %i detected and working\n", id); - scsi_device_identify(sd, lun); + x54x_log("SCSI Target ID %i detected and working\n", id); + scsi_device_identify(sd, lun); - x54x_log("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); - x54x_log("CDB Length %i\n", req->CmdBlock.common.CdbLength); - x54x_log("CCB Opcode %x\n", req->CmdBlock.common.Opcode); - if ((req->CmdBlock.common.Opcode > 0x04) && (req->CmdBlock.common.Opcode != 0x81)) { - x54x_log("Invalid opcode: %02X\n", - req->CmdBlock.common.ControlByte); - x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_INVALID_OP_CODE, SCSI_STATUS_OK, MBI_ERROR); - dev->callback_sub_phase = 4; - return; - } - if (req->CmdBlock.common.Opcode == 0x81) { - x54x_log("Bus reset opcode\n"); - scsi_device_reset(sd); - x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - dev->callback_sub_phase = 4; - return; - } + x54x_log("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); + x54x_log("CDB Length %i\n", req->CmdBlock.common.CdbLength); + x54x_log("CCB Opcode %x\n", req->CmdBlock.common.Opcode); + if ((req->CmdBlock.common.Opcode > 0x04) && (req->CmdBlock.common.Opcode != 0x81)) { + x54x_log("Invalid opcode: %02X\n", + req->CmdBlock.common.ControlByte); + x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_INVALID_OP_CODE, SCSI_STATUS_OK, MBI_ERROR); + dev->callback_sub_phase = 4; + return; + } + if (req->CmdBlock.common.Opcode == 0x81) { + x54x_log("Bus reset opcode\n"); + scsi_device_reset(sd); + x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + dev->callback_sub_phase = 4; + return; + } - dev->callback_sub_phase = 1; + dev->callback_sub_phase = 1; } } - static void x54x_req_abort(x54x_t *dev, uint32_t CCBPointer) { CCBU CmdBlock; /* Fetch data from the Command Control Block. */ - dma_bm_read(CCBPointer, (uint8_t *)&CmdBlock, sizeof(CCB32), dev->transfer_size); + dma_bm_read(CCBPointer, (uint8_t *) &CmdBlock, sizeof(CCB32), dev->transfer_size); x54x_add_to_period(dev, sizeof(CCB32)); x54x_mbi_setup(dev, CCBPointer, &CmdBlock, - 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); + 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); dev->callback_sub_phase = 4; } - static uint32_t x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32) { Mailbox_t MailboxOut; - uint32_t Outgoing; - uint32_t ccbp; - uint32_t Addr; - uint32_t Cur; + uint32_t Outgoing; + uint32_t ccbp; + uint32_t Addr; + uint32_t Cur; if (dev->MailboxIsBIOS) { - Addr = dev->BIOSMailboxOutAddr; - Cur = dev->BIOSMailboxOutPosCur; + Addr = dev->BIOSMailboxOutAddr; + Cur = dev->BIOSMailboxOutPosCur; } else { - Addr = dev->MailboxOutAddr; - Cur = dev->MailboxOutPosCur; + Addr = dev->MailboxOutAddr; + Cur = dev->MailboxOutPosCur; } if (dev->flags & X54X_MBX_24BIT) { - Outgoing = Addr + (Cur * sizeof(Mailbox_t)); - dma_bm_read(Outgoing, (uint8_t *)&MailboxOut, sizeof(Mailbox_t), dev->transfer_size); - x54x_add_to_period(dev, sizeof(Mailbox_t)); + Outgoing = Addr + (Cur * sizeof(Mailbox_t)); + dma_bm_read(Outgoing, (uint8_t *) &MailboxOut, sizeof(Mailbox_t), dev->transfer_size); + x54x_add_to_period(dev, sizeof(Mailbox_t)); - ccbp = *(uint32_t *) &MailboxOut; - Mailbox32->CCBPointer = (ccbp >> 24) | ((ccbp >> 8) & 0xff00) | ((ccbp << 8) & 0xff0000); - Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; + ccbp = *(uint32_t *) &MailboxOut; + Mailbox32->CCBPointer = (ccbp >> 24) | ((ccbp >> 8) & 0xff00) | ((ccbp << 8) & 0xff0000); + Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; } else { - Outgoing = Addr + (Cur * sizeof(Mailbox32_t)); + Outgoing = Addr + (Cur * sizeof(Mailbox32_t)); - dma_bm_read(Outgoing, (uint8_t *)Mailbox32, sizeof(Mailbox32_t), dev->transfer_size); - x54x_add_to_period(dev, sizeof(Mailbox32_t)); + dma_bm_read(Outgoing, (uint8_t *) Mailbox32, sizeof(Mailbox32_t), dev->transfer_size); + x54x_add_to_period(dev, sizeof(Mailbox32_t)); } - return(Outgoing); + return (Outgoing); } - uint8_t x54x_mbo_process(x54x_t *dev) { Mailbox32_t mb32; - dev->ToRaise = 0; + dev->ToRaise = 0; dev->Outgoing = x54x_mbo(dev, &mb32); if (mb32.u.out.ActionCode == MBO_START) { - x54x_log("Start Mailbox Command\n"); - x54x_req_setup(dev, mb32.CCBPointer, &mb32); + x54x_log("Start Mailbox Command\n"); + x54x_req_setup(dev, mb32.CCBPointer, &mb32); } else if (!dev->MailboxIsBIOS && (mb32.u.out.ActionCode == MBO_ABORT)) { - x54x_log("Abort Mailbox Command\n"); - x54x_req_abort(dev, mb32.CCBPointer); + x54x_log("Abort Mailbox Command\n"); + x54x_req_abort(dev, mb32.CCBPointer); } /* else { - x54x_log("Invalid action code: %02X\n", mb32.u.out.ActionCode); + x54x_log("Invalid action code: %02X\n", mb32.u.out.ActionCode); } */ if ((mb32.u.out.ActionCode == MBO_START) || (!dev->MailboxIsBIOS && (mb32.u.out.ActionCode == MBO_ABORT))) { - /* We got the mailbox, decrease the number of pending requests. */ - if (dev->MailboxIsBIOS) - dev->BIOSMailboxReq--; - else - dev->MailboxReq--; + /* We got the mailbox, decrease the number of pending requests. */ + if (dev->MailboxIsBIOS) + dev->BIOSMailboxReq--; + else + dev->MailboxReq--; - return(1); + return (1); } - return(0); + return (0); } - static void x54x_do_mail(x54x_t *dev) { @@ -1226,99 +1183,97 @@ x54x_do_mail(x54x_t *dev) dev->MailboxIsBIOS = 0; if (dev->is_aggressive_mode) { - aggressive = dev->is_aggressive_mode(dev); - x54x_log("Processing mailboxes in %s mode...\n", aggressive ? "aggressive" : "strict"); - }/* else { - x54x_log("Defaulting to process mailboxes in %s mode...\n", aggressive ? "aggressive" : "strict"); - }*/ + aggressive = dev->is_aggressive_mode(dev); + x54x_log("Processing mailboxes in %s mode...\n", aggressive ? "aggressive" : "strict"); + } /* else { + x54x_log("Defaulting to process mailboxes in %s mode...\n", aggressive ? "aggressive" : "strict"); + }*/ if (!dev->MailboxCount) { - x54x_log("x54x_do_mail(): No Mailboxes\n"); - return; + x54x_log("x54x_do_mail(): No Mailboxes\n"); + return; } if (aggressive) { - /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ - for (dev->MailboxOutPosCur = 0; dev->MailboxOutPosCur < dev->MailboxCount; dev->MailboxOutPosCur++) { - if (x54x_mbo_process(dev)) - break; - } + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + for (dev->MailboxOutPosCur = 0; dev->MailboxOutPosCur < dev->MailboxCount; dev->MailboxOutPosCur++) { + if (x54x_mbo_process(dev)) + break; + } } else { - /* Strict round robin mode - only process the current mailbox and advance the pointer if successful. */ - if (x54x_mbo_process(dev)) { - dev->MailboxOutPosCur++; - dev->MailboxOutPosCur %= dev->MailboxCount; - } + /* Strict round robin mode - only process the current mailbox and advance the pointer if successful. */ + if (x54x_mbo_process(dev)) { + dev->MailboxOutPosCur++; + dev->MailboxOutPosCur %= dev->MailboxCount; + } } } - static void x54x_cmd_done(x54x_t *dev, int suppress); - static void x54x_cmd_callback(void *priv) { - double period; + double period; x54x_t *dev = (x54x_t *) priv; int mailboxes_present, bios_mailboxes_present; - mailboxes_present = (!(dev->Status & STAT_INIT) && dev->MailboxInit && dev->MailboxReq); + mailboxes_present = (!(dev->Status & STAT_INIT) && dev->MailboxInit && dev->MailboxReq); bios_mailboxes_present = (dev->ven_callback && dev->BIOSMailboxInit && dev->BIOSMailboxReq); - dev->temp_period = 0; + dev->temp_period = 0; dev->media_period = 0.0; switch (dev->callback_sub_phase) { - case 0: - /* Sub-phase 0 - Look for mailbox. */ - if ((dev->callback_phase == 0) && mailboxes_present) - x54x_do_mail(dev); - else if ((dev->callback_phase == 1) && bios_mailboxes_present) - dev->ven_callback(dev); + case 0: + /* Sub-phase 0 - Look for mailbox. */ + if ((dev->callback_phase == 0) && mailboxes_present) + x54x_do_mail(dev); + else if ((dev->callback_phase == 1) && bios_mailboxes_present) + dev->ven_callback(dev); - if (dev->ven_callback && (dev->callback_sub_phase == 0)) - dev->callback_phase ^= 1; - break; - case 1: - /* Sub-phase 1 - Do SCSI command phase 0. */ - x54x_log("%s: Callback: Process SCSI request\n", dev->name); - x54x_scsi_cmd(dev); - break; - case 2: - /* Sub-phase 2 - Do SCSI command phase 1. */ - x54x_log("%s: Callback: Process SCSI request\n", dev->name); - x54x_scsi_cmd_phase1(dev); - break; - case 3: - /* Sub-phase 3 - Request sense. */ - x54x_log("%s: Callback: Process SCSI request\n", dev->name); - x54x_request_sense(dev); - break; - case 4: - /* Sub-phase 4 - Notify. */ - x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); - x54x_notify(dev); + if (dev->ven_callback && (dev->callback_sub_phase == 0)) + dev->callback_phase ^= 1; + break; + case 1: + /* Sub-phase 1 - Do SCSI command phase 0. */ + x54x_log("%s: Callback: Process SCSI request\n", dev->name); + x54x_scsi_cmd(dev); + break; + case 2: + /* Sub-phase 2 - Do SCSI command phase 1. */ + x54x_log("%s: Callback: Process SCSI request\n", dev->name); + x54x_scsi_cmd_phase1(dev); + break; + case 3: + /* Sub-phase 3 - Request sense. */ + x54x_log("%s: Callback: Process SCSI request\n", dev->name); + x54x_request_sense(dev); + break; + case 4: + /* Sub-phase 4 - Notify. */ + x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); + x54x_notify(dev); - /* Go back to lookup phase. */ - dev->callback_sub_phase = 0; + /* Go back to lookup phase. */ + dev->callback_sub_phase = 0; - /* Toggle normal/BIOS mailbox - only has an effect if both types of mailboxes - have been initialized. */ - if (dev->ven_callback) - dev->callback_phase ^= 1; + /* Toggle normal/BIOS mailbox - only has an effect if both types of mailboxes + have been initialized. */ + if (dev->ven_callback) + dev->callback_phase ^= 1; - /* Add to period and raise the IRQ if needed. */ - x54x_add_to_period(dev, 1); + /* Add to period and raise the IRQ if needed. */ + x54x_add_to_period(dev, 1); - if (dev->ToRaise) - raise_irq(dev, 0, dev->ToRaise); - break; - default: - x54x_log("Invalid sub-phase: %02X\n", dev->callback_sub_phase); - break; + if (dev->ToRaise) + raise_irq(dev, 0, dev->ToRaise); + break; + default: + x54x_log("Invalid sub-phase: %02X\n", dev->callback_sub_phase); + break; } period = (1000000.0 / dev->ha_bps) * ((double) dev->temp_period); @@ -1326,119 +1281,120 @@ x54x_cmd_callback(void *priv) // x54x_log("Temporary period: %lf us (%" PRIi64 " periods)\n", dev->timer.period, dev->temp_period); } - static uint8_t x54x_in(uint16_t port, void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; uint8_t ret; switch (port & 3) { - case 0: - default: - ret = dev->Status; - break; + case 0: + default: + ret = dev->Status; + break; - case 1: - ret = dev->DataBuf[dev->DataReply]; - if (dev->DataReplyLeft) { - dev->DataReply++; - dev->DataReplyLeft--; - if (! dev->DataReplyLeft) - x54x_cmd_done(dev, 0); - } - break; + case 1: + ret = dev->DataBuf[dev->DataReply]; + if (dev->DataReplyLeft) { + dev->DataReply++; + dev->DataReplyLeft--; + if (!dev->DataReplyLeft) + x54x_cmd_done(dev, 0); + } + break; - case 2: - if (dev->flags & X54X_INT_GEOM_WRITABLE) - ret = dev->Interrupt; - else - ret = dev->Interrupt & ~0x70; - break; + case 2: + if (dev->flags & X54X_INT_GEOM_WRITABLE) + ret = dev->Interrupt; + else + ret = dev->Interrupt & ~0x70; + break; - case 3: - /* Bits according to ASPI4DOS.SYS v3.36: - 0 Not checked - 1 Must be 0 - 2 Must be 0-0-0-1 - 3 Must be 0 - 4 Must be 0-1-0-0 - 5 Must be 0 - 6 Not checked - 7 Not checked - */ - if (dev->flags & X54X_INT_GEOM_WRITABLE) - ret = dev->Geometry; - else { - switch(dev->Geometry) { - case 0: default: ret = 'A'; break; - case 1: ret = 'D'; break; - case 2: ret = 'A'; break; - case 3: ret = 'P'; break; - } - ret ^= 1; - dev->Geometry++; - dev->Geometry &= 0x03; - break; - } - break; + case 3: + /* Bits according to ASPI4DOS.SYS v3.36: + 0 Not checked + 1 Must be 0 + 2 Must be 0-0-0-1 + 3 Must be 0 + 4 Must be 0-1-0-0 + 5 Must be 0 + 6 Not checked + 7 Not checked + */ + if (dev->flags & X54X_INT_GEOM_WRITABLE) + ret = dev->Geometry; + else { + switch (dev->Geometry) { + case 0: + default: + ret = 'A'; + break; + case 1: + ret = 'D'; + break; + case 2: + ret = 'A'; + break; + case 3: + ret = 'P'; + break; + } + ret ^= 1; + dev->Geometry++; + dev->Geometry &= 0x03; + break; + } + break; } #ifdef ENABLE_X54X_LOG if (port == 0x0332) - x54x_log("x54x_in(): %04X, %02X, %08X\n", port, ret, dev->DataReplyLeft); + x54x_log("x54x_in(): %04X, %02X, %08X\n", port, ret, dev->DataReplyLeft); else - x54x_log("x54x_in(): %04X, %02X\n", port, ret); + x54x_log("x54x_in(): %04X, %02X\n", port, ret); #endif - return(ret); + return (ret); } - static uint16_t x54x_inw(uint16_t port, void *priv) { - return((uint16_t) x54x_in(port, priv)); + return ((uint16_t) x54x_in(port, priv)); } - static uint32_t x54x_inl(uint16_t port, void *priv) { - return((uint32_t) x54x_in(port, priv)); + return ((uint32_t) x54x_in(port, priv)); } - static uint8_t x54x_readb(uint32_t port, void *priv) { - return(x54x_in(port & 3, priv)); + return (x54x_in(port & 3, priv)); } - static uint16_t x54x_readw(uint32_t port, void *priv) { - return(x54x_inw(port & 3, priv)); + return (x54x_inw(port & 3, priv)); } - static uint32_t x54x_readl(uint32_t port, void *priv) { - return(x54x_inl(port & 3, priv)); + return (x54x_inl(port & 3, priv)); } - static void x54x_reset_poll(void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; dev->Status = STAT_INIT | STAT_IDLE; } - static void x54x_reset(x54x_t *dev) { @@ -1446,487 +1402,473 @@ x54x_reset(x54x_t *dev) clear_irq(dev); if (dev->flags & X54X_INT_GEOM_WRITABLE) - dev->Geometry = 0x80; + dev->Geometry = 0x80; else - dev->Geometry = 0x00; - dev->callback_phase = 0; + dev->Geometry = 0x00; + dev->callback_phase = 0; dev->callback_sub_phase = 0; timer_stop(&dev->timer); timer_set_delay_u64(&dev->timer, (uint64_t) (dev->timer.period * ((double) TIMER_USEC))); - dev->Command = 0xFF; - dev->CmdParam = 0; + dev->Command = 0xFF; + dev->CmdParam = 0; dev->CmdParamLeft = 0; dev->flags |= X54X_MBX_24BIT; - dev->MailboxInPosCur = 0; + dev->MailboxInPosCur = 0; dev->MailboxOutInterrupts = 0; - dev->PendingInterrupt = 0; - dev->IrqEnabled = 1; - dev->MailboxCount = 0; - dev->MailboxOutPosCur = 0; + dev->PendingInterrupt = 0; + dev->IrqEnabled = 1; + dev->MailboxCount = 0; + dev->MailboxOutPosCur = 0; /* Reset all devices on controller reset. */ for (i = 0; i < 16; i++) - scsi_device_reset(&scsi_devices[dev->bus][i]); + scsi_device_reset(&scsi_devices[dev->bus][i]); if (dev->ven_reset) - dev->ven_reset(dev); + dev->ven_reset(dev); } - void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset) { /* Say hello! */ x54x_log("%s %s (IO=0x%04X, IRQ=%d, DMA=%d, BIOS @%05lX) ID=%d\n", - dev->vendor, dev->name, dev->Base, dev->Irq, dev->DmaChannel, - dev->rom_addr, dev->HostID); + dev->vendor, dev->name, dev->Base, dev->Irq, dev->DmaChannel, + dev->rom_addr, dev->HostID); x54x_reset(dev); if (Reset) { - dev->Status = STAT_STST; - timer_set_delay_u64(&dev->ResetCB, X54X_RESET_DURATION_US * TIMER_USEC); + dev->Status = STAT_STST; + timer_set_delay_u64(&dev->ResetCB, X54X_RESET_DURATION_US * TIMER_USEC); } else - dev->Status = STAT_INIT | STAT_IDLE; + dev->Status = STAT_INIT | STAT_IDLE; } - static void x54x_out(uint16_t port, uint8_t val, void *priv) { ReplyInquireSetupInformation *ReplyISI; - x54x_t *dev = (x54x_t *)priv; - MailboxInit_t *mbi; - int i = 0; - BIOSCMD *cmd; - uint16_t cyl = 0; - int suppress = 0; - uint32_t FIFOBuf; - uint8_t reset; - addr24 Address; - uint8_t host_id = dev->HostID; - uint8_t irq = 0; + x54x_t *dev = (x54x_t *) priv; + MailboxInit_t *mbi; + int i = 0; + BIOSCMD *cmd; + uint16_t cyl = 0; + int suppress = 0; + uint32_t FIFOBuf; + uint8_t reset; + addr24 Address; + uint8_t host_id = dev->HostID; + uint8_t irq = 0; x54x_log("%s: Write Port 0x%02X, Value %02X\n", dev->name, port, val); switch (port & 3) { - case 0: - if ((val & CTRL_HRST) || (val & CTRL_SRST)) { - reset = (val & CTRL_HRST); - x54x_log("Reset completed = %x\n", reset); - x54x_reset_ctrl(dev, reset); - x54x_log("Controller reset\n"); - break; - } + case 0: + if ((val & CTRL_HRST) || (val & CTRL_SRST)) { + reset = (val & CTRL_HRST); + x54x_log("Reset completed = %x\n", reset); + x54x_reset_ctrl(dev, reset); + x54x_log("Controller reset\n"); + break; + } - if (val & CTRL_SCRST) { - /* Reset all devices on SCSI bus reset. */ - for (i = 0; i < 16; i++) - scsi_device_reset(&scsi_devices[dev->bus][i]); - } + if (val & CTRL_SCRST) { + /* Reset all devices on SCSI bus reset. */ + for (i = 0; i < 16; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); + } - if (val & CTRL_IRST) { - clear_irq(dev); - x54x_log("Interrupt reset\n"); - } - break; + if (val & CTRL_IRST) { + clear_irq(dev); + x54x_log("Interrupt reset\n"); + } + break; - case 1: - /* Fast path for the mailbox execution command. */ - if ((val == CMD_START_SCSI) && (dev->Command == 0xff)) { - dev->MailboxReq++; - x54x_log("Start SCSI command\n"); - return; - } - if (dev->ven_fast_cmds) { - if (dev->Command == 0xff) { - if (dev->ven_fast_cmds(dev, val)) - return; - } - } + case 1: + /* Fast path for the mailbox execution command. */ + if ((val == CMD_START_SCSI) && (dev->Command == 0xff)) { + dev->MailboxReq++; + x54x_log("Start SCSI command\n"); + return; + } + if (dev->ven_fast_cmds) { + if (dev->Command == 0xff) { + if (dev->ven_fast_cmds(dev, val)) + return; + } + } - if (dev->Command == 0xff) { - dev->Command = val; - dev->CmdParam = 0; - dev->CmdParamLeft = 0; + if (dev->Command == 0xff) { + dev->Command = val; + dev->CmdParam = 0; + dev->CmdParamLeft = 0; - dev->Status &= ~(STAT_INVCMD | STAT_IDLE); - x54x_log("%s: Operation Code 0x%02X\n", dev->name, val); - switch (dev->Command) { - case CMD_MBINIT: - dev->CmdParamLeft = sizeof(MailboxInit_t); - break; + dev->Status &= ~(STAT_INVCMD | STAT_IDLE); + x54x_log("%s: Operation Code 0x%02X\n", dev->name, val); + switch (dev->Command) { + case CMD_MBINIT: + dev->CmdParamLeft = sizeof(MailboxInit_t); + break; - case CMD_BIOSCMD: - dev->CmdParamLeft = 10; - break; + case CMD_BIOSCMD: + dev->CmdParamLeft = 10; + break; - case CMD_EMBOI: - case CMD_BUSON_TIME: - case CMD_BUSOFF_TIME: - case CMD_DMASPEED: - case CMD_RETSETUP: - case CMD_ECHO: - case CMD_OPTIONS: - dev->CmdParamLeft = 1; - break; + case CMD_EMBOI: + case CMD_BUSON_TIME: + case CMD_BUSOFF_TIME: + case CMD_DMASPEED: + case CMD_RETSETUP: + case CMD_ECHO: + case CMD_OPTIONS: + dev->CmdParamLeft = 1; + break; - case CMD_SELTIMEOUT: - dev->CmdParamLeft = 4; - break; + case CMD_SELTIMEOUT: + dev->CmdParamLeft = 4; + break; - case CMD_WRITE_CH2: - case CMD_READ_CH2: - dev->CmdParamLeft = 3; - break; + case CMD_WRITE_CH2: + case CMD_READ_CH2: + dev->CmdParamLeft = 3; + break; - default: - if (dev->get_ven_param_len) - dev->CmdParamLeft = dev->get_ven_param_len(dev); - break; - } - } else { - dev->CmdBuf[dev->CmdParam] = val; - dev->CmdParam++; - dev->CmdParamLeft--; + default: + if (dev->get_ven_param_len) + dev->CmdParamLeft = dev->get_ven_param_len(dev); + break; + } + } else { + dev->CmdBuf[dev->CmdParam] = val; + dev->CmdParam++; + dev->CmdParamLeft--; - if (dev->ven_cmd_phase1) - dev->ven_cmd_phase1(dev); - } + if (dev->ven_cmd_phase1) + dev->ven_cmd_phase1(dev); + } - if (! dev->CmdParamLeft) { - x54x_log("Running Operation Code 0x%02X\n", dev->Command); - switch (dev->Command) { - case CMD_NOP: /* No Operation */ - dev->DataReplyLeft = 0; - break; + if (!dev->CmdParamLeft) { + x54x_log("Running Operation Code 0x%02X\n", dev->Command); + switch (dev->Command) { + case CMD_NOP: /* No Operation */ + dev->DataReplyLeft = 0; + break; - case CMD_MBINIT: /* mailbox initialization */ - dev->flags |= X54X_MBX_24BIT; + case CMD_MBINIT: /* mailbox initialization */ + dev->flags |= X54X_MBX_24BIT; - mbi = (MailboxInit_t *)dev->CmdBuf; + mbi = (MailboxInit_t *) dev->CmdBuf; - dev->MailboxInit = 1; - dev->MailboxCount = mbi->Count; - dev->MailboxOutAddr = ADDR_TO_U32(mbi->Address); - dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t)); + dev->MailboxInit = 1; + dev->MailboxCount = mbi->Count; + dev->MailboxOutAddr = ADDR_TO_U32(mbi->Address); + dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t)); - x54x_log("Initialize Mailbox: MBO=0x%08lx, MBI=0x%08lx, %d entries at 0x%08lx\n", - dev->MailboxOutAddr, - dev->MailboxInAddr, - mbi->Count, - ADDR_TO_U32(mbi->Address)); + x54x_log("Initialize Mailbox: MBO=0x%08lx, MBI=0x%08lx, %d entries at 0x%08lx\n", + dev->MailboxOutAddr, + dev->MailboxInAddr, + mbi->Count, + ADDR_TO_U32(mbi->Address)); - dev->Status &= ~STAT_INIT; - dev->DataReplyLeft = 0; - x54x_log("Mailbox init: "); - break; + dev->Status &= ~STAT_INIT; + dev->DataReplyLeft = 0; + x54x_log("Mailbox init: "); + break; - case CMD_BIOSCMD: /* execute BIOS */ - cmd = (BIOSCMD *)dev->CmdBuf; - if (!(dev->flags & X54X_LBA_BIOS)) { - /* 1640 uses LBA. */ - cyl = ((cmd->u.chs.cyl & 0xff) << 8) | ((cmd->u.chs.cyl >> 8) & 0xff); - cmd->u.chs.cyl = cyl; - } - if (dev->flags & X54X_LBA_BIOS) { - /* 1640 uses LBA. */ - x54x_log("BIOS LBA=%06lx (%lu)\n", - lba32_blk(cmd), - lba32_blk(cmd)); - } else { - cmd->u.chs.head &= 0xf; - cmd->u.chs.sec &= 0x1f; - x54x_log("BIOS CHS=%04X/%02X%02X\n", - cmd->u.chs.cyl, - cmd->u.chs.head, - cmd->u.chs.sec); - } - dev->DataBuf[0] = x54x_bios_command(dev, dev->max_id, cmd, !!(dev->flags & X54X_LBA_BIOS)); - x54x_log("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); - dev->DataReplyLeft = 1; - break; + case CMD_BIOSCMD: /* execute BIOS */ + cmd = (BIOSCMD *) dev->CmdBuf; + if (!(dev->flags & X54X_LBA_BIOS)) { + /* 1640 uses LBA. */ + cyl = ((cmd->u.chs.cyl & 0xff) << 8) | ((cmd->u.chs.cyl >> 8) & 0xff); + cmd->u.chs.cyl = cyl; + } + if (dev->flags & X54X_LBA_BIOS) { + /* 1640 uses LBA. */ + x54x_log("BIOS LBA=%06lx (%lu)\n", + lba32_blk(cmd), + lba32_blk(cmd)); + } else { + cmd->u.chs.head &= 0xf; + cmd->u.chs.sec &= 0x1f; + x54x_log("BIOS CHS=%04X/%02X%02X\n", + cmd->u.chs.cyl, + cmd->u.chs.head, + cmd->u.chs.sec); + } + dev->DataBuf[0] = x54x_bios_command(dev, dev->max_id, cmd, !!(dev->flags & X54X_LBA_BIOS)); + x54x_log("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); + dev->DataReplyLeft = 1; + break; - case CMD_INQUIRY: /* Inquiry */ - memcpy(dev->DataBuf, dev->fw_rev, 4); - x54x_log("Adapter inquiry: %c %c %c %c\n", dev->fw_rev[0], dev->fw_rev[1], dev->fw_rev[2], dev->fw_rev[3]); - dev->DataReplyLeft = 4; - break; + case CMD_INQUIRY: /* Inquiry */ + memcpy(dev->DataBuf, dev->fw_rev, 4); + x54x_log("Adapter inquiry: %c %c %c %c\n", dev->fw_rev[0], dev->fw_rev[1], dev->fw_rev[2], dev->fw_rev[3]); + dev->DataReplyLeft = 4; + break; - case CMD_EMBOI: /* enable MBO Interrupt */ - if (dev->CmdBuf[0] <= 1) { - dev->MailboxOutInterrupts = dev->CmdBuf[0]; - x54x_log("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); - suppress = 1; - } else { - dev->Status |= STAT_INVCMD; - } - dev->DataReplyLeft = 0; - break; + case CMD_EMBOI: /* enable MBO Interrupt */ + if (dev->CmdBuf[0] <= 1) { + dev->MailboxOutInterrupts = dev->CmdBuf[0]; + x54x_log("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); + suppress = 1; + } else { + dev->Status |= STAT_INVCMD; + } + dev->DataReplyLeft = 0; + break; - case CMD_SELTIMEOUT: /* Selection Time-out */ - dev->DataReplyLeft = 0; - break; + case CMD_SELTIMEOUT: /* Selection Time-out */ + dev->DataReplyLeft = 0; + break; - case CMD_BUSON_TIME: /* bus-on time */ - dev->BusOnTime = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - x54x_log("Bus-on time: %d\n", dev->CmdBuf[0]); - break; + case CMD_BUSON_TIME: /* bus-on time */ + dev->BusOnTime = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + x54x_log("Bus-on time: %d\n", dev->CmdBuf[0]); + break; - case CMD_BUSOFF_TIME: /* bus-off time */ - dev->BusOffTime = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - x54x_log("Bus-off time: %d\n", dev->CmdBuf[0]); - break; + case CMD_BUSOFF_TIME: /* bus-off time */ + dev->BusOffTime = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + x54x_log("Bus-off time: %d\n", dev->CmdBuf[0]); + break; - case CMD_DMASPEED: /* DMA Transfer Rate */ - dev->ATBusSpeed = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - x54x_log("DMA transfer rate: %02X\n", dev->CmdBuf[0]); - break; + case CMD_DMASPEED: /* DMA Transfer Rate */ + dev->ATBusSpeed = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + x54x_log("DMA transfer rate: %02X\n", dev->CmdBuf[0]); + break; - case CMD_RETDEVS: /* return Installed Devices */ - memset(dev->DataBuf, 0x00, 8); + case CMD_RETDEVS: /* return Installed Devices */ + memset(dev->DataBuf, 0x00, 8); - if (dev->ven_get_host_id) - host_id = dev->ven_get_host_id(dev); + if (dev->ven_get_host_id) + host_id = dev->ven_get_host_id(dev); - for (i=0; i<8; i++) { - dev->DataBuf[i] = 0x00; + for (i = 0; i < 8; i++) { + dev->DataBuf[i] = 0x00; - /* Skip the HA .. */ - if (i == host_id) continue; + /* Skip the HA .. */ + if (i == host_id) + continue; - /* TODO: Query device for LUN's. */ - if (scsi_device_present(&scsi_devices[dev->bus][i])) - dev->DataBuf[i] |= 1; - } - dev->DataReplyLeft = i; - break; + /* TODO: Query device for LUN's. */ + if (scsi_device_present(&scsi_devices[dev->bus][i])) + dev->DataBuf[i] |= 1; + } + dev->DataReplyLeft = i; + break; - case CMD_RETCONF: /* return Configuration */ - if (dev->ven_get_dma) - dev->DataBuf[0] = (1 << dev->ven_get_dma(dev)); - else - dev->DataBuf[0] = (1 << dev->DmaChannel); + case CMD_RETCONF: /* return Configuration */ + if (dev->ven_get_dma) + dev->DataBuf[0] = (1 << dev->ven_get_dma(dev)); + else + dev->DataBuf[0] = (1 << dev->DmaChannel); - if (dev->ven_get_irq) - irq = dev->ven_get_irq(dev); - else - irq = dev->Irq; + if (dev->ven_get_irq) + irq = dev->ven_get_irq(dev); + else + irq = dev->Irq; - if (irq >= 9) - dev->DataBuf[1]=(1<<(irq-9)); - else - dev->DataBuf[1]=0; - if (dev->ven_get_host_id) - dev->DataBuf[2] = dev->ven_get_host_id(dev); - else - dev->DataBuf[2] = dev->HostID; - x54x_log("Configuration data: %02X %02X %02X\n", dev->DataBuf[0], dev->DataBuf[1], dev->DataBuf[2]); - dev->DataReplyLeft = 3; - break; + if (irq >= 9) + dev->DataBuf[1] = (1 << (irq - 9)); + else + dev->DataBuf[1] = 0; + if (dev->ven_get_host_id) + dev->DataBuf[2] = dev->ven_get_host_id(dev); + else + dev->DataBuf[2] = dev->HostID; + x54x_log("Configuration data: %02X %02X %02X\n", dev->DataBuf[0], dev->DataBuf[1], dev->DataBuf[2]); + dev->DataReplyLeft = 3; + break; - case CMD_RETSETUP: /* return Setup */ - ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; - memset(ReplyISI, 0x00, sizeof(ReplyInquireSetupInformation)); + case CMD_RETSETUP: /* return Setup */ + ReplyISI = (ReplyInquireSetupInformation *) dev->DataBuf; + memset(ReplyISI, 0x00, sizeof(ReplyInquireSetupInformation)); - ReplyISI->uBusTransferRate = dev->ATBusSpeed; - ReplyISI->uPreemptTimeOnBus = dev->BusOnTime; - ReplyISI->uTimeOffBus = dev->BusOffTime; - ReplyISI->cMailbox = dev->MailboxCount; - U32_TO_ADDR(ReplyISI->MailboxAddress, dev->MailboxOutAddr); + ReplyISI->uBusTransferRate = dev->ATBusSpeed; + ReplyISI->uPreemptTimeOnBus = dev->BusOnTime; + ReplyISI->uTimeOffBus = dev->BusOffTime; + ReplyISI->cMailbox = dev->MailboxCount; + U32_TO_ADDR(ReplyISI->MailboxAddress, dev->MailboxOutAddr); - if (dev->get_ven_data) - dev->get_ven_data(dev); + if (dev->get_ven_data) + dev->get_ven_data(dev); - dev->DataReplyLeft = dev->CmdBuf[0]; - x54x_log("Return Setup Information: %d (length: %i)\n", dev->CmdBuf[0], sizeof(ReplyInquireSetupInformation)); - break; + dev->DataReplyLeft = dev->CmdBuf[0]; + x54x_log("Return Setup Information: %d (length: %i)\n", dev->CmdBuf[0], sizeof(ReplyInquireSetupInformation)); + break; - case CMD_ECHO: /* ECHO data */ - dev->DataBuf[0] = dev->CmdBuf[0]; - dev->DataReplyLeft = 1; - break; + case CMD_ECHO: /* ECHO data */ + dev->DataBuf[0] = dev->CmdBuf[0]; + dev->DataReplyLeft = 1; + break; - case CMD_WRITE_CH2: /* write channel 2 buffer */ - dev->DataReplyLeft = 0; - Address.hi = dev->CmdBuf[0]; - Address.mid = dev->CmdBuf[1]; - Address.lo = dev->CmdBuf[2]; - FIFOBuf = ADDR_TO_U32(Address); - x54x_log("Adaptec LocalRAM: Reading 64 bytes at %08X\n", FIFOBuf); - dma_bm_read(FIFOBuf, dev->dma_buffer, 64, dev->transfer_size); - break; + case CMD_WRITE_CH2: /* write channel 2 buffer */ + dev->DataReplyLeft = 0; + Address.hi = dev->CmdBuf[0]; + Address.mid = dev->CmdBuf[1]; + Address.lo = dev->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + x54x_log("Adaptec LocalRAM: Reading 64 bytes at %08X\n", FIFOBuf); + dma_bm_read(FIFOBuf, dev->dma_buffer, 64, dev->transfer_size); + break; - case CMD_READ_CH2: /* write channel 2 buffer */ - dev->DataReplyLeft = 0; - Address.hi = dev->CmdBuf[0]; - Address.mid = dev->CmdBuf[1]; - Address.lo = dev->CmdBuf[2]; - FIFOBuf = ADDR_TO_U32(Address); - x54x_log("Adaptec LocalRAM: Writing 64 bytes at %08X\n", FIFOBuf); - dma_bm_write(FIFOBuf, dev->dma_buffer, 64, dev->transfer_size); - break; + case CMD_READ_CH2: /* write channel 2 buffer */ + dev->DataReplyLeft = 0; + Address.hi = dev->CmdBuf[0]; + Address.mid = dev->CmdBuf[1]; + Address.lo = dev->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + x54x_log("Adaptec LocalRAM: Writing 64 bytes at %08X\n", FIFOBuf); + dma_bm_write(FIFOBuf, dev->dma_buffer, 64, dev->transfer_size); + break; - case CMD_OPTIONS: /* Set adapter options */ - if (dev->CmdParam == 1) - dev->CmdParamLeft = dev->CmdBuf[0]; - dev->DataReplyLeft = 0; - break; + case CMD_OPTIONS: /* Set adapter options */ + if (dev->CmdParam == 1) + dev->CmdParamLeft = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + break; - default: - if (dev->ven_cmds) - suppress = dev->ven_cmds(dev); - else { - dev->DataReplyLeft = 0; - dev->Status |= STAT_INVCMD; - } - break; - } - } + default: + if (dev->ven_cmds) + suppress = dev->ven_cmds(dev); + else { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + } + } - if (dev->DataReplyLeft) - dev->Status |= STAT_DFULL; - else if (!dev->CmdParamLeft) - x54x_cmd_done(dev, suppress); - break; + if (dev->DataReplyLeft) + dev->Status |= STAT_DFULL; + else if (!dev->CmdParamLeft) + x54x_cmd_done(dev, suppress); + break; - case 2: - if (dev->flags & X54X_INT_GEOM_WRITABLE) - dev->Interrupt = val; - break; + case 2: + if (dev->flags & X54X_INT_GEOM_WRITABLE) + dev->Interrupt = val; + break; - case 3: - if (dev->flags & X54X_INT_GEOM_WRITABLE) - dev->Geometry = val; - break; + case 3: + if (dev->flags & X54X_INT_GEOM_WRITABLE) + dev->Geometry = val; + break; } } - static void x54x_outw(uint16_t port, uint16_t val, void *priv) { x54x_out(port, val & 0xFF, priv); } - static void x54x_outl(uint16_t port, uint32_t val, void *priv) { x54x_out(port, val & 0xFF, priv); } - static void x54x_writeb(uint32_t port, uint8_t val, void *priv) { x54x_out(port & 3, val, priv); } - static void x54x_writew(uint32_t port, uint16_t val, void *priv) { x54x_outw(port & 3, val, priv); } - static void x54x_writel(uint32_t port, uint32_t val, void *priv) { x54x_outl(port & 3, val, priv); } - static int x54x_is_32bit(x54x_t *dev) { int bit32 = 0; if (dev->card_bus & DEVICE_PCI) - bit32 = 1; + bit32 = 1; else if ((dev->card_bus & DEVICE_MCA) && (dev->flags & X54X_32BIT)) - bit32 = 1; + bit32 = 1; return bit32; } - void x54x_io_set(x54x_t *dev, uint32_t base, uint8_t len) { if (x54x_is_32bit(dev)) { - x54x_log("x54x: [PCI] Setting I/O handler at %04X\n", base); - io_sethandler(base, len, - x54x_in, x54x_inw, x54x_inl, + x54x_log("x54x: [PCI] Setting I/O handler at %04X\n", base); + io_sethandler(base, len, + x54x_in, x54x_inw, x54x_inl, x54x_out, x54x_outw, x54x_outl, dev); } else { - x54x_log("x54x: [ISA] Setting I/O handler at %04X\n", base); - io_sethandler(base, len, - x54x_in, x54x_inw, NULL, + x54x_log("x54x: [ISA] Setting I/O handler at %04X\n", base); + io_sethandler(base, len, + x54x_in, x54x_inw, NULL, x54x_out, x54x_outw, NULL, dev); } } - void x54x_io_remove(x54x_t *dev, uint32_t base, uint8_t len) { x54x_log("x54x: Removing I/O handler at %04X\n", base); if (x54x_is_32bit(dev)) { - io_removehandler(base, len, - x54x_in, x54x_inw, x54x_inl, - x54x_out, x54x_outw, x54x_outl, dev); + io_removehandler(base, len, + x54x_in, x54x_inw, x54x_inl, + x54x_out, x54x_outw, x54x_outl, dev); } else { - io_removehandler(base, len, - x54x_in, x54x_inw, NULL, - x54x_out, x54x_outw, NULL, dev); + io_removehandler(base, len, + x54x_in, x54x_inw, NULL, + x54x_out, x54x_outw, NULL, dev); } } - void x54x_mem_init(x54x_t *dev, uint32_t addr) { if (x54x_is_32bit(dev)) { - mem_mapping_add(&dev->mmio_mapping, addr, 0x20, - x54x_readb, x54x_readw, x54x_readl, - x54x_writeb, x54x_writew, x54x_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); + mem_mapping_add(&dev->mmio_mapping, addr, 0x20, + x54x_readb, x54x_readw, x54x_readl, + x54x_writeb, x54x_writew, x54x_writel, + NULL, MEM_MAPPING_EXTERNAL, dev); } else { - mem_mapping_add(&dev->mmio_mapping, addr, 0x20, - x54x_readb, x54x_readw, NULL, - x54x_writeb, x54x_writew, NULL, - NULL, MEM_MAPPING_EXTERNAL, dev); + mem_mapping_add(&dev->mmio_mapping, addr, 0x20, + x54x_readb, x54x_readw, NULL, + x54x_writeb, x54x_writew, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); } } - void x54x_mem_enable(x54x_t *dev) { mem_mapping_enable(&dev->mmio_mapping); } - void x54x_mem_set_addr(x54x_t *dev, uint32_t base) { mem_mapping_set_addr(&dev->mmio_mapping, base, 0x20); } - void x54x_mem_disable(x54x_t *dev) { mem_mapping_disable(&dev->mmio_mapping); } - /* General initialization routine for all boards. */ void * x54x_init(const device_t *info) @@ -1935,11 +1877,12 @@ x54x_init(const device_t *info) /* Allocate control block and set up basic stuff. */ dev = malloc(sizeof(x54x_t)); - if (dev == NULL) return(dev); + if (dev == NULL) + return (dev); memset(dev, 0x00, sizeof(x54x_t)); dev->type = info->local; - dev->card_bus = info->flags; + dev->card_bus = info->flags; dev->callback_phase = 0; timer_add(&dev->ResetCB, x54x_reset_poll, dev, 0); @@ -1947,47 +1890,45 @@ x54x_init(const device_t *info) dev->timer.period = 10.0; timer_set_delay_u64(&dev->timer, (uint64_t) (dev->timer.period * ((double) TIMER_USEC))); - if (x54x_is_32bit(dev)) - dev->transfer_size = 4; - else - dev->transfer_size = 2; + if (x54x_is_32bit(dev)) + dev->transfer_size = 4; + else + dev->transfer_size = 2; - return(dev); + return (dev); } - void x54x_close(void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; if (dev) { - /* Tell the timer to terminate. */ - timer_stop(&dev->timer); + /* Tell the timer to terminate. */ + timer_stop(&dev->timer); - /* Also terminate the reset callback timer. */ - timer_disable(&dev->ResetCB); + /* Also terminate the reset callback timer. */ + timer_disable(&dev->ResetCB); - dev->MailboxInit = dev->BIOSMailboxInit = 0; - dev->MailboxCount = dev->BIOSMailboxCount = 0; - dev->MailboxReq = dev->BIOSMailboxReq = 0; + dev->MailboxInit = dev->BIOSMailboxInit = 0; + dev->MailboxCount = dev->BIOSMailboxCount = 0; + dev->MailboxReq = dev->BIOSMailboxReq = 0; - if (dev->ven_data) - free(dev->ven_data); + if (dev->ven_data) + free(dev->ven_data); - if (dev->nvr != NULL) - free(dev->nvr); + if (dev->nvr != NULL) + free(dev->nvr); - free(dev); - dev = NULL; + free(dev); + dev = NULL; } } - void x54x_device_reset(void *priv) { - x54x_t *dev = (x54x_t *)priv; + x54x_t *dev = (x54x_t *) priv; x54x_reset_ctrl(dev, 1);