Implemented ATAPI DMA transfer modes.

This commit is contained in:
SarahW 2018-03-15 19:36:30 +00:00
commit 6602368cc4
9 changed files with 289 additions and 54 deletions

View file

@ -45,6 +45,7 @@
#define WIN_SETIDLE1 0xE3
#define WIN_CHECK_POWER_MODE 0xE5
#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */
#define WIN_SET_FEATURES 0xEF
/** Evaluate to non-zero if the currently selected drive is an ATAPI device */
#define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM)
@ -93,8 +94,8 @@ IDE *ext_ide;
char ide_fn[7][512];
int (*ide_bus_master_read_sector)(int channel, uint8_t *data);
int (*ide_bus_master_write_sector)(int channel, uint8_t *data);
int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size);
int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size);
void (*ide_bus_master_set_irq)(int channel);
int idecallback[2] = {0, 0};
@ -582,7 +583,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
return;
case WIN_IDENTIFY: /* Identify Device */
case 0xEF:
case WIN_SET_FEATURES:
// output=3;
// timetolive=500;
ide->atastat = BUSY_STAT;
@ -593,7 +594,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case WIN_PACKETCMD: /* ATAPI Packet */
if (ide->type == IDE_CDROM)
atapi_command_start(&ide->atapi);
atapi_command_start(&ide->atapi, ide->cylprecomp);
ide->atastat = BUSY_STAT;
timer_process();
@ -932,9 +933,9 @@ void callbackide(int ide_board)
}
ide->pos=0;
if (ide_bus_master_read_sector)
if (ide_bus_master_read_data)
{
if (ide_bus_master_read_sector(ide_board, &ide->sector_buffer[ide->sector_pos*512]))
if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512))
idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/
else
{
@ -1010,9 +1011,9 @@ void callbackide(int ide_board)
goto abort_cmd;
}
if (ide_bus_master_write_sector)
if (ide_bus_master_write_data)
{
if (ide_bus_master_write_sector(ide_board, (uint8_t *)ide->buffer))
if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512))
idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/
else
{
@ -1138,7 +1139,6 @@ void callbackide(int ide_board)
return;
case WIN_SETIDLE1: /* Idle */
case 0xEF:
goto abort_cmd;
case WIN_IDENTIFY: /* Identify Device */
@ -1161,7 +1161,18 @@ void callbackide(int ide_board)
}
return;
case WIN_SET_FEATURES:
if (ide->type == IDE_NONE)
goto abort_cmd;
if (!IDE_DRIVE_IS_CDROM(ide))
goto abort_cmd;
if (!atapi_dev->bus.devices[0]->atapi_set_feature(ide->cylprecomp, ide->secount, atapi_dev->bus.device_data[0]))
goto abort_cmd;
ide->atastat = READY_STAT | DSC_STAT;
ide_irq_raise(ide);
return;
case WIN_CHECK_POWER_MODE:
if (ide->type == IDE_NONE)
{
@ -1291,10 +1302,10 @@ static void ide_close(void *p)
{
}
void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel))
void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size), int (*write_data)(int channel, uint8_t *data, int size), void (*set_irq)(int channel))
{
ide_bus_master_read_sector = read_sector;
ide_bus_master_write_sector = write_sector;
ide_bus_master_read_data = read_data;
ide_bus_master_write_data = write_data;
ide_bus_master_set_irq = set_irq;
}

View file

@ -15,9 +15,13 @@ extern void ide_pri_enable();
extern void ide_sec_enable();
extern void ide_pri_disable();
extern void ide_sec_disable();
extern void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel));
extern void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size), int (*write_data)(int channel, uint8_t *data, int size), void (*set_irq)(int channel));
void ide_irq_raise(struct IDE *ide);
extern int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size);
extern int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size);
extern void (*ide_bus_master_set_irq)(int channel);
#include "ide_atapi.h"
extern int ideboard;
@ -47,4 +51,12 @@ extern device_t ide_device;
#define ABRT_ERR 0x04 /* Command aborted */
#define MCR_ERR 0x08 /* Media change request */
#define FEATURE_SET_TRANSFER_MODE 0x03
#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d
#define FEATURE_ENABLE_IRQ_SERVICE 0x5e
#define FEATURE_DISABLE_REVERT 0x66
#define FEATURE_ENABLE_REVERT 0xcc
#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd
#define FEATURE_DISABLE_IRQ_SERVICE 0xde
#endif //__IDE__

View file

@ -17,6 +17,11 @@
#define ATAPI_STATE_READ_DATA_WAIT 8
#define ATAPI_STATE_WRITE_DATA 9
#define ATAPI_STATE_WRITE_DATA_WAIT 10
#define ATAPI_STATE_RETRY_READ_DMA 11
#define ATAPI_STATE_RETRY_WRITE_DMA 12
#define FEATURES_DMA 0x01
#define FEATURES_OVERLAP 0x02
ATAPI *atapi;
@ -94,9 +99,11 @@ static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed)
return 0;
}
void atapi_command_start(atapi_device_t *atapi)
void atapi_command_start(atapi_device_t *atapi, uint8_t features)
{
scsi_bus_t *bus = &atapi->bus;
atapi->use_dma = features & 1;
scsi_bus_update(bus, BUS_SEL | BUS_SETDATA(1 << 0));
if (!(scsi_bus_read(bus) & BUS_BSY))
@ -243,19 +250,47 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG))
{
case 0:
atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT;
atapi_dev->data_read_pos = scsi_dev->get_bytes_required(scsi_data);
if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len)
atapi_dev->data_read_pos = atapi_dev->max_transfer_len;
atapi_dev->data_write_pos = 0;
*atapi_dev->cylinder = atapi_dev->data_read_pos;
if (atapi_dev->use_dma)
{
if (ide_bus_master_write_data)
{
if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos))
{
atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
}
else
atapi_dev->data_write_pos = atapi_dev->data_read_pos; {
atapi_dev->bus_state = 0;
atapi_dev->state = ATAPI_STATE_WRITE_DATA;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
}
}
else
{
atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
}
}
else
{
if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len)
atapi_dev->data_read_pos = atapi_dev->max_transfer_len;
atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT;
// pclog("WRITE_DATA: bytes=%i\n", *atapi_dev->cylinder);
*atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT);
atapi_dev->bus_state = BUS_REQ;
ide_irq_raise(atapi_dev->ide);
*atapi_dev->cylinder = atapi_dev->data_read_pos;
// pclog("WRITE_DATA: bytes=%i\n", *atapi_dev->cylinder);
*atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT);
atapi_dev->bus_state = BUS_REQ;
ide_irq_raise(atapi_dev->ide);
}
break;
case BUS_IO:
@ -391,12 +426,36 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
if ((scsi_bus_read(&atapi_dev->bus) & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO)
break;
}
atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT;
*atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT);
*atapi_dev->cylinder = atapi_dev->data_write_pos;
// pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder);
atapi_dev->bus_state = BUS_IO | BUS_REQ;
ide_irq_raise(atapi_dev->ide);
if (atapi_dev->use_dma)
{
if (ide_bus_master_read_data)
{
if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos))
{
atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
}
else
{
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 6*IDE_TIME;
}
}
else
{
atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
}
}
else
{
atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT;
*atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT);
*atapi_dev->cylinder = atapi_dev->data_write_pos;
// pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder);
atapi_dev->bus_state = BUS_IO | BUS_REQ;
ide_irq_raise(atapi_dev->ide);
}
}
break;
@ -473,5 +532,34 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
idecallback[atapi_dev->board] = 6 * IDE_TIME;
}
break;
case ATAPI_STATE_RETRY_READ_DMA:
{
if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos))
{
idecallback[atapi_dev->board] = 1*IDE_TIME;
}
else
{
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 6*IDE_TIME;
}
}
break;
case ATAPI_STATE_RETRY_WRITE_DMA:
{
if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos))
{
idecallback[atapi_dev->board] = 1*IDE_TIME;
}
else
{
atapi_dev->bus_state = 0;
atapi_dev->state = ATAPI_STATE_WRITE_DATA;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
}
}
break;
}
}

View file

@ -53,11 +53,13 @@ typedef struct atapi_device_t
uint8_t *atastat;
uint8_t *error;
int *cylinder;
int use_dma;
} atapi_device_t;
void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val);
uint16_t atapi_data_read(atapi_device_t *atapi_dev);
void atapi_command_start(atapi_device_t *atapi);
void atapi_command_start(atapi_device_t *atapi, uint8_t features);
uint8_t atapi_read_iir(atapi_device_t *atapi_dev);
uint8_t atapi_read_drq(atapi_device_t *atapi_dev);
void atapi_process_packet(atapi_device_t *atapi_dev);

View file

@ -216,21 +216,21 @@ uint8_t piix_bus_master_read(uint16_t port, void *priv)
return 0xff;
}
int piix_bus_master_sector_read(int channel, uint8_t *data)
int piix_bus_master_data_read(int channel, uint8_t *data, int size)
{
int transferred = 0;
if (!(piix_busmaster[channel].status & 1))
return 1; /*DMA disabled*/
while (transferred < 512)
while (transferred < size)
{
if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot)
fatal("DMA on channel %i - Read count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
if (piix_busmaster[channel].count < (size - transferred) && piix_busmaster[channel].eot)
fatal("DMA on channel %i - Read count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot, size);
mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+511);
mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+(size-1));
if (piix_busmaster[channel].count < (512 - transferred))
if (piix_busmaster[channel].count < (size - transferred))
{
// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count);
if (piix_busmaster[channel].addr < (mem_size * 1024))
@ -246,17 +246,17 @@ int piix_bus_master_sector_read(int channel, uint8_t *data)
}
else
{
// pclog("Transferring larger - %i bytes\n", 512 - transferred);
// pclog("Transferring larger - %i bytes\n", size - transferred);
if (piix_busmaster[channel].addr < (mem_size * 1024))
{
int count = 512 - transferred;
int count = size - transferred;
if ((piix_busmaster[channel].addr + count) > (mem_size * 1024))
count = (mem_size * 1024) - piix_busmaster[channel].addr;
memcpy(&ram[piix_busmaster[channel].addr], data + transferred, count);
}
piix_busmaster[channel].addr += (512 - transferred);
piix_busmaster[channel].count -= (512 - transferred);
transferred += (512 - transferred);
piix_busmaster[channel].addr += (size - transferred);
piix_busmaster[channel].count -= (size - transferred);
transferred += (size - transferred);
}
// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
@ -275,19 +275,19 @@ int piix_bus_master_sector_read(int channel, uint8_t *data)
}
return 0;
}
int piix_bus_master_sector_write(int channel, uint8_t *data)
int piix_bus_master_data_write(int channel, uint8_t *data, int size)
{
int transferred = 0;
if (!(piix_busmaster[channel].status & 1))
return 1; /*DMA disabled*/
while (transferred < 512)
while (transferred < size)
{
if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot)
fatal("DMA on channel %i - Write count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
if (piix_busmaster[channel].count < (size - transferred) && piix_busmaster[channel].eot)
fatal("DMA on channel %i - Write count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot, size);
if (piix_busmaster[channel].count < (512 - transferred))
if (piix_busmaster[channel].count < (size - transferred))
{
// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count);
if (piix_busmaster[channel].addr < (mem_size * 1024))
@ -303,17 +303,17 @@ int piix_bus_master_sector_write(int channel, uint8_t *data)
}
else
{
// pclog("Transferring larger - %i bytes\n", 512 - transferred);
// pclog("Transferring larger - %i bytes\n", size - transferred);
if (piix_busmaster[channel].addr < (mem_size * 1024))
{
int count = 512 - transferred;
int count = size - transferred;
if ((piix_busmaster[channel].addr + count) > (mem_size * 1024))
count = (mem_size * 1024) - piix_busmaster[channel].addr;
memcpy(data + transferred, &ram[piix_busmaster[channel].addr], count);
}
piix_busmaster[channel].addr += (512 - transferred);
piix_busmaster[channel].count -= (512 - transferred);
transferred += (512 - transferred);
piix_busmaster[channel].addr += (size - transferred);
piix_busmaster[channel].count -= (size - transferred);
transferred += (size - transferred);
}
// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
@ -377,7 +377,7 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00;
card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00;
ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq);
ide_set_bus_master(piix_bus_master_data_read, piix_bus_master_data_write, piix_bus_master_set_irq);
pci_set_card_routing(pci_a, PCI_INTA);
pci_set_card_routing(pci_b, PCI_INTB);

View file

@ -18,6 +18,7 @@ typedef struct scsi_device_t
int (*get_bytes_required)(void *p);
void (*atapi_identify)(uint16_t *buffer, void *p);
int (*atapi_set_feature)(uint8_t feature, uint8_t val, void *p);
uint8_t (*read)(void *p);
void (*write)(uint8_t val, void *p);

View file

@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include "ibm.h"
#include "ide.h"
#include "ide_atapi.h"
#include "scsi.h"
#include "scsi_cd.h"
@ -194,6 +195,8 @@ typedef struct scsi_cd_data_t
int is_atapi;
atapi_device_t *atapi_dev;
int pio_mode, mdma_mode;
} scsi_cd_data_t;
static void scsi_add_data(scsi_cd_data_t *data, uint8_t val)
@ -1171,16 +1174,72 @@ static int scsi_cd_get_bytes_required(void *p)
static void scsi_cd_atapi_identify(uint16_t *buffer, void *p)
{
scsi_cd_data_t *data = p;
memset(buffer, 0, 512);
buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */
ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */
ide_padstr((char *)(buffer + 23), "v1.0", 8); /* Firmware */
ide_padstr((char *)(buffer + 27), "PCemCD", 40); /* Model */
buffer[49] = 0x200; /* LBA supported */
buffer[49] = 0x300; /*DMA and LBA supported*/
buffer[51] = 120;
buffer[52] = 120;
buffer[53] = 2; /*Words 64-70 are valid*/
buffer[62] = 0x0000;
buffer[63] = 0x0007 | (0x100 << data->mdma_mode); /*Multi-word DMA 0, 1 & 2*/
buffer[64] = 0x0003; /*PIO Modes 3 & 4*/
if (data->pio_mode >= 3)
buffer[64] |= (0x100 << (data->pio_mode - 3));
buffer[65] = 120; /*Minimum multi-word cycle time*/
buffer[66] = 120; /*Recommended multi-word cycle time*/
buffer[67] = 120; /*Minimum PIO cycle time*/
buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */
}
static int scsi_cd_atapi_set_feature(uint8_t feature, uint8_t val, void *p)
{
scsi_cd_data_t *data = p;
switch (feature)
{
case FEATURE_SET_TRANSFER_MODE:
if (!(val & 0xfe))
{
/*Default transfer mode*/
data->pio_mode = 0;
return 1;
}
else if ((val & 0xf8) == 0x08)
{
/*PIO transfer mode*/
if ((val & 7) > 4)
return 0;
data->pio_mode = (val & 7);
return 1;
}
else if ((val & 0xf8) == 0x20)
{
/*Multi-word DMA transfer mode*/
if ((val & 7) > 2)
return 0;
data->mdma_mode = (val & 7);
return 1;
}
return 0; /*Invalid data*/
case FEATURE_ENABLE_IRQ_OVERLAPPED:
case FEATURE_ENABLE_IRQ_SERVICE:
case FEATURE_DISABLE_REVERT:
case FEATURE_DISABLE_IRQ_OVERLAPPED:
case FEATURE_DISABLE_IRQ_SERVICE:
case FEATURE_ENABLE_REVERT:
return 1;
}
return 0; /*Feature not supported*/
}
scsi_device_t scsi_cd =
{
scsi_cd_init,
@ -1195,6 +1254,7 @@ scsi_device_t scsi_cd =
scsi_cd_get_bytes_required,
scsi_cd_atapi_identify,
scsi_cd_atapi_set_feature,
scsi_cd_read,
scsi_cd_write,

View file

@ -826,6 +826,7 @@ scsi_device_t scsi_hd =
scsi_hd_get_sense_key,
scsi_hd_get_bytes_required,
NULL,
NULL,
scsi_hd_read,

View file

@ -4,6 +4,7 @@
#include <string.h>
#include "ibm.h"
#include "hdd_file.h"
#include "ide.h"
#include "ide_atapi.h"
#include "scsi.h"
#include "scsi_zip.h"
@ -73,6 +74,8 @@ typedef struct scsi_zip_data
atapi_device_t *atapi_dev;
int read_only;
int pio_mode, mdma_mode;
} scsi_zip_data;
static scsi_zip_data *zip_data;
@ -1077,16 +1080,72 @@ static int scsi_zip_get_bytes_required(void *p)
static void scsi_zip_atapi_identify(uint16_t *buffer, void *p)
{
scsi_zip_data *data = p;
memset(buffer, 0, 512);
buffer[0] = 0x8000 | (0<<8) | 0x80 | (2<<5); /* ATAPI device, direct-access device, removable media, accelerated DRQ */
ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */
ide_padstr((char *)(buffer + 23), "E.08", 8); /* Firmware */
ide_padstr((char *)(buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */
buffer[49] = 0x200; /* LBA supported */
buffer[49] = 0x300; /*DMA and LBA supported*/
buffer[51] = 120;
buffer[52] = 120;
buffer[53] = 2; /*Words 64-70 are valid*/
buffer[62] = 0x0000;
buffer[63] = 0x0003 | (0x100 << data->mdma_mode); /*Multi-word DMA 0 & 1*/
buffer[64] = 0x0001; /*PIO Mode 3*/
if (data->pio_mode >= 3)
buffer[64] |= (0x100 << (data->pio_mode - 3));
buffer[65] = 120; /*Minimum multi-word cycle time*/
buffer[66] = 120; /*Recommended multi-word cycle time*/
buffer[67] = 120; /*Minimum PIO cycle time*/
buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */
}
static int scsi_zip_atapi_set_feature(uint8_t feature, uint8_t val, void *p)
{
scsi_zip_data *data = p;
switch (feature)
{
case FEATURE_SET_TRANSFER_MODE:
if (!(val & 0xfe))
{
/*Default transfer mode*/
data->pio_mode = 0;
return 1;
}
else if ((val & 0xf8) == 0x08)
{
/*PIO transfer mode*/
if ((val & 7) > 3)
return 0;
data->pio_mode = (val & 7);
return 1;
}
else if ((val & 0xf8) == 0x20)
{
/*Multi-word DMA transfer mode*/
if ((val & 7) > 1)
return 0;
data->mdma_mode = (val & 7);
return 1;
}
return 0; /*Invalid data*/
case FEATURE_ENABLE_IRQ_OVERLAPPED:
case FEATURE_ENABLE_IRQ_SERVICE:
case FEATURE_DISABLE_REVERT:
case FEATURE_DISABLE_IRQ_OVERLAPPED:
case FEATURE_DISABLE_IRQ_SERVICE:
case FEATURE_ENABLE_REVERT:
return 1;
}
return 0; /*Feature not supported*/
}
scsi_device_t scsi_zip =
{
scsi_zip_init,
@ -1101,6 +1160,7 @@ scsi_device_t scsi_zip =
scsi_zip_get_bytes_required,
scsi_zip_atapi_identify,
scsi_zip_atapi_set_feature,
scsi_zip_read,
scsi_zip_write,