This commit is contained in:
Matt Harlum 2023-03-22 20:04:20 +00:00
parent cdcb9b04d9
commit ccc6d3f1ca
9 changed files with 510 additions and 228 deletions

103
ata.c
View File

@ -1,3 +1,4 @@
#include <devices/scsidisk.h>
#include <exec/execbase.h>
#include <exec/types.h>
#include <exec/devices.h>
@ -16,10 +17,15 @@
#include <clib/debug_protos.h>
#endif
#define NOTIMER
#define WAIT_TIMEOUT_MS 100
#define WAIT_TIMEOUT_MS 500
/**
* ata_wait_not_busy
*
* Wait with a timeout for the unit to report that it is not busy
*
* returns false on timeout
*/
bool ata_wait_not_busy(struct IDEUnit *unit) {
#ifndef NOTIMER
struct Device *TimerBase = unit->TimeReq->tr_node.io_Device;
@ -40,6 +46,14 @@ bool ata_wait_not_busy(struct IDEUnit *unit) {
}
}
/**
* ata_wait_ready
*
* Wait with a timeout for the unit to report that it is ready
*
* returns false on timeout
*/
bool ata_wait_ready(struct IDEUnit *unit) {
#ifndef NOTIMER
struct Device *TimerBase = unit->TimeReq->tr_node.io_Device;
@ -59,27 +73,43 @@ bool ata_wait_ready(struct IDEUnit *unit) {
}
}
/**
* ata_wait_drq
*
* Wait with a timeout for the unit to set drq
*
* returns false on timeout
*/
bool ata_wait_drq(struct IDEUnit *unit) {
/*
#ifndef NOTIMER
struct Device *TimerBase = unit->TimeReq->tr_node.io_Device;
struct timeval start, now;
GetSysTime(&start);
#endif
*/
#if DEBUG >= 2
KPrintF("wait_drq\n");
#endif
while (1) {
if (*(volatile BYTE *)unit->drive->status_command& ata_drq) return true;
/*
#ifndef NOTIMER
GetSysTime(&now);
if (now.tv_micro >= (start.tv_micro + (WAIT_TIMEOUT_MS*1000))) return false;
#endif
*/
}
}
/**
* ata_identify
*
* Send an IDENTIFY command to the device and place the results in the buffer
*
* returns fals on error
*/
bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
{
#ifndef NOTIMER
@ -97,9 +127,8 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
*unit->drive->status_command = ATA_CMD_IDENTIFY;
volatile UBYTE *status = unit->drive->status_command;
UBYTE curstatus = *status;
#if DEBUG >= 2
KPrintF("Drive Status: %04x%04x %04x%04x\n",status, curstatus);
KPrintF("Drive Status: %04x%04x %04x%04x\n",status, *status);
#endif
if (*status == 0) return false; // No drive there?
@ -130,6 +159,13 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
return true;
}
/**
* ata_init_unit
*
* Initialize a unit, check if it is there and responding
*
* returns false on error
*/
bool ata_init_unit(struct IDEUnit *unit) {
struct ExecBase *SysBase = unit->SysBase;
@ -190,14 +226,29 @@ bool ata_init_unit(struct IDEUnit *unit) {
return true;
}
/**
* ata_read
*
* Read a block from the unit
* @param buffer Destination buffer
* @param lba LBA Address
* @param count Number of blocks to transfer
* @param actual Pointer to the io reqquests io_Actual
* @param unit Pointer to the unit structure
*/
BYTE ata_read(APTR *buffer, ULONG lba, UBYTE count, ULONG *actual, struct IDEUnit *unit) {
#if DEBUG > 1
KPrintF("ata_read");
#endif
*actual = 0;
if (count == 0) return TDERR_TooFewSecs;
BYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
*unit->drive->devHead = (UBYTE)(drvSel | ((lba >> 24) & 0x0F));
if (!ata_wait_ready(unit))
return TDERR_NotSpecified;
return HFERR_BadStatus;
*unit->drive->sectorCount = count;
*unit->drive->lbaLow = (UBYTE)(lba);
@ -208,8 +259,15 @@ BYTE ata_read(APTR *buffer, ULONG lba, UBYTE count, ULONG *actual, struct IDEUni
UWORD offset = 0;
for (int block = 0; block < count; block++) {
if (!ata_wait_drq(unit) || (*unit->drive->error_features && ata_error))
if (!ata_wait_drq(unit))
return HFERR_BadStatus;
if (*unit->drive->error_features && ata_error) {
#if DEBUG > 1
KPrintF("ATA ERROR!!!");
#endif
return TDERR_NotSpecified;
}
for (int i=0; i<(unit->blockSize / 2); i++) {
((UWORD *)buffer)[offset] = *unit->drive->data;
@ -221,14 +279,30 @@ BYTE ata_read(APTR *buffer, ULONG lba, UBYTE count, ULONG *actual, struct IDEUni
return 0;
}
/**
* ata_write
*
* Read a block from the unit
* @param buffer Source buffer
* @param lba LBA Address
* @param count Number of blocks to transfer
* @param actual Pointer to the io reqquests io_Actual
* @param unit Pointer to the unit structure
*/
BYTE ata_write(APTR *buffer, ULONG lba, UBYTE count, ULONG *actual, struct IDEUnit *unit) {
#if DEBUG > 1
KPrintF("ata_write");
#endif
*actual = 0;
if (count == 0) return TDERR_TooFewSecs;
BYTE drvSel = (unit->primary) ? 0xE0 : 0xF0;
*unit->drive->devHead = (UBYTE)(drvSel | ((lba >> 24) & 0x0F));
if (!ata_wait_ready(unit))
return TDERR_NotSpecified;
return HFERR_BadStatus;
*unit->drive->sectorCount = count;
*unit->drive->lbaLow = (UBYTE)(lba);
@ -239,8 +313,15 @@ BYTE ata_write(APTR *buffer, ULONG lba, UBYTE count, ULONG *actual, struct IDEUn
UWORD offset = 0;
for (int block = 0; block < count; block++) {
if (!ata_wait_drq(unit) || (unit->drive->error_features && ata_error))
if (!ata_wait_drq(unit))
return HFERR_BadStatus;
if (*unit->drive->error_features && ata_error) {
#if DEBUG > 1
KPrintF("ATA ERROR!!!");
#endif
return TDERR_NotSpecified;
}
for (int i=0; i<(unit->blockSize / 2); i++) {
*unit->drive->data = ((UWORD *)buffer)[offset];

View File

@ -1,22 +1,27 @@
#ifndef _DEVICE_H
#define _DEVICE_H
#include <proto/exec.h>
#include <exec/resident.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/errors.h>
#include <exec/libraries.h>
#include <exec/ports.h>
#include <exec/resident.h>
#include <exec/tasks.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#define MANUF_ID 2092
#define DEV_ID 6
#define MAX_UNITS 4
typedef struct Drive {
/**
* Drive struct
*
* Each register spaced 512 bytes apart
* To use this code with other boards you may need to adjust these sizes
*/
struct Drive {
UWORD data[256];
UBYTE error_features[512];
UBYTE sectorCount[512];
@ -25,14 +30,14 @@ typedef struct Drive {
UBYTE lbaHigh[512];
UBYTE devHead[512];
UBYTE status_command[512];
} Drive;
};
struct IDEUnit {
struct Unit io_unit;
struct ConfigDev *cd;
struct ExecBase *SysBase;
struct timerequest *TimeReq;
Drive *drive;
struct Drive *drive;
UBYTE unitNum;
BOOL primary;
BOOL present;

158
driver.c
View File

@ -13,12 +13,13 @@
#include <proto/exec.h>
#include <proto/expansion.h>
#include <string.h>
#include <stdio.h>
#include "idetask.h"
#include "device.h"
#include "ata.h"
#include "device.h"
#include "idetask.h"
#include "newstyle.h"
#include "td64.h"
#if DEBUG
#include <clib/debug_protos.h>
@ -53,6 +54,12 @@ char device_name[] = DEVICE_NAME;
const char device_id_string[] = DEVICE_ID_STRING;
const char task_name[] = TASK_NAME;
/** set_dev_name
*
* Try to set a unique drive name
* will prepend 2nd/3rd/4th. etc to the beginning of device_name
*/
char * set_dev_name(struct DeviceBase *dev) {
struct ExecBase *SysBase = dev->SysBase;
@ -66,7 +73,7 @@ char * set_dev_name(struct DeviceBase *dev) {
*(ULONG *)devName = device_prefix[i]; // Add prefix to start of device name string in a hacky way
} else {
#if DEBUG > 0
KPrintF("Device name: %s",devName);
KPrintF("Device name: %s\n",devName);
#endif
return devName;
}
@ -77,7 +84,12 @@ char * set_dev_name(struct DeviceBase *dev) {
return NULL;
}
void Cleanup(struct DeviceBase *dev) {
/**
* Cleanup
*
* Free used resources back to the system
*/
static void Cleanup(struct DeviceBase *dev) {
#if DEBUG > 0
KPrintF("Cleaning up...\n");
#endif
@ -89,8 +101,11 @@ void Cleanup(struct DeviceBase *dev) {
if (dev->units) FreeMem(dev->units,sizeof(struct IDEUnit) * MAX_UNITS);
}
//static struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase, BPTR seg_list, struct DeviceBase *dev)
/**
* init_device
*
* Scan for drives and initialize the driver if any are found
*/
static struct Library __attribute__((used)) * init_device(struct ExecBase *SysBase asm("a6"), BPTR seg_list asm("a0"), struct DeviceBase *dev asm("d0"))
{
dev->SysBase = SysBase;
@ -229,21 +244,38 @@ static BPTR __attribute__((used)) expunge(struct DeviceBase *dev asm("a6"))
#if DEBUG >= 2
KPrintF((CONST_STRPTR) "running expunge()\n");
#endif
/*
if (dev->lib.lib_OpenCnt != 0)
{
dev->lib.lib_Flags |= LIBF_DELEXP;
return 0;
}
if (dev->Task != NULL) {
FreeMem(dev->units,sizeof(struct IDEUnit) * MAX_UNITS);
struct MsgPort *mp = NULL;
struct IOStdReq *ioreq = NULL;
if ((mp = CreatePort(NULL,0)) == NULL)
return 0;
if ((ioreq = CreateStdIO(mp)) == NULL) {
DeletePort(mp);
return 0;
}
ioreq->io_Command = CMD_DIE;
PutMsg(dev->TaskMP,(struct Message *)ioreq);
WaitPort(mp);
if (ioreq) DeleteStdIO(ioreq);
if (mp) DeletePort(mp);
}
BPTR seg_list = dev->saved_seg_list;
Remove(&dev->lib.lib_Node);
FreeMem((char *)dev - dev->lib.lib_NegSize, dev->lib.lib_NegSize + dev->lib.lib_PosSize);
return seg_list;
*/
return 0;
}
/* device dependent open function
@ -255,9 +287,13 @@ static void __attribute__((used)) open(struct DeviceBase *dev asm("a6"), struct
#if DEBUG >= 2
KPrintF((CONST_STRPTR) "running open() for unitnum %x%x\n",unitnum);
#endif
ioreq->io_Error = IOERR_OPENFAIL;
ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;
ioreq->io_Error = IOERR_OPENFAIL;
if (dev->Task == NULL) {
ioreq->io_Error = IOERR_OPENFAIL;
}
if (unitnum >= MAX_UNITS || dev->units[unitnum].present == false) {
ioreq->io_Error = TDERR_BadUnitNum;
@ -285,32 +321,79 @@ static BPTR __attribute__((used)) close(struct DeviceBase *dev asm("a6"), struct
KPrintF((CONST_STRPTR) "running close()\n");
#endif
dev->lib.lib_OpenCnt--;
/* No Expunge yet...
ioreq->io_Device = NULL;
ioreq->io_Unit = NULL;
if (dev->lib.lib_OpenCnt == 0 && (dev->lib.lib_Flags & LIBF_DELEXP))
return expunge(dev);
*/
return 0;
}
/* device dependent beginio function */
static UWORD supported_commands[] =
{
CMD_CLEAR,
CMD_UPDATE,
CMD_READ,
CMD_WRITE,
TD_PROTSTATUS,
TD_CHANGENUM,
TD_CHANGESTATE,
TD_GETDRIVETYPE,
TD_PROTSTATUS,
TD_READ64,
TD_WRITE64,
TD_FORMAT64,
NSCMD_DEVICEQUERY,
NSCMD_TD_READ64,
NSCMD_TD_WRITE64,
NSCMD_TD_FORMAT64,
0
};
/**
* begin_io
*
* Action an IO Request
*/
static void __attribute__((used)) begin_io(struct DeviceBase *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
{
#if DEBUG >= 2
KPrintF((CONST_STRPTR) "running begin_io()\n");
#endif
// struct ExecBase *SysBase = dev->SysBase;
ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;
ioreq->io_Error = TDERR_NotSpecified;
if (dev->Task == NULL) {
ioreq->io_Error = IOERR_OPENFAIL;
}
if (ioreq == NULL || ioreq->io_Unit == 0) return;
switch (ioreq->io_Command) {
case CMD_CLEAR:
case CMD_UPDATE:
case TD_CHANGENUM:
ioreq->io_Actual = 1;
ioreq->io_Error = 0;
break;
case TD_CHANGESTATE:
case TD_GETDRIVETYPE:
case TD_PROTSTATUS:
ioreq->io_Actual = 0;
ioreq->io_Error = 0;
break;
case HD_SCSICMD:
case CMD_READ:
case TD_FORMAT:
case CMD_WRITE:
case TD_READ64:
case TD_WRITE64:
case TD_FORMAT64:
case NSCMD_TD_READ64:
case NSCMD_TD_WRITE64:
case NSCMD_TD_FORMAT64:
ioreq->io_Flags &= ~IOF_QUICK;
PutMsg(dev->TaskMP,&ioreq->io_Message);
#if DEBUG >= 2
@ -318,6 +401,23 @@ static void __attribute__((used)) begin_io(struct DeviceBase *dev asm("a6"), str
#endif
break;
case NSCMD_DEVICEQUERY:
if (ioreq->io_Length >= sizeof(struct NSDeviceQueryResult))
{
struct NSDeviceQueryResult *result = ioreq->io_Data;
result->DevQueryFormat = 0;
result->SizeAvailable = sizeof(struct NSDeviceQueryResult);
result->DeviceType = NSDEVTYPE_TRACKDISK;
result->DeviceSubType = 0;
result->SupportedCommands = supported_commands;
ioreq->io_Actual = sizeof(struct NSDeviceQueryResult);
ioreq->io_Error = 0;
}
else {
ioreq->io_Error = IOERR_BADLENGTH;
}
break;
default:
#if DEBUG >= 2
KPrintF("Unknown command %x%x\n", ioreq->io_Command);
@ -330,7 +430,11 @@ static void __attribute__((used)) begin_io(struct DeviceBase *dev asm("a6"), str
}
/* device dependent abortio function */
/**
* abort_io
*
* Abort io request
*/
static ULONG __attribute__((used)) abort_io(struct Library *dev asm("a6"), struct IOStdReq *ioreq asm("a1"))
{
#if DEBUG >= 2
@ -351,13 +455,17 @@ static const ULONG device_vectors[] =
-1 //function table end marker
};
static struct Library __attribute__((used)) * init(BPTR seg_list asm("a0"), struct ExecBase *SysPtr asm("a6"))
/**
* init
*
* Create the device and add it to the system if init_device succeeds
*/
static struct Library __attribute__((used)) * init(BPTR seg_list asm("a0"), struct ExecBase *sb asm("a6"))
{
#if DEBUG >= 1
KPrintF("Init driver.\n");
#endif
SysBase = SysPtr;
SysBase = sb;
struct Device *mydev = (struct Device *)MakeLibrary((ULONG *)&device_vectors, // Vectors
NULL, // InitStruct data
(APTR)init_device, // Init function

174
idetask.c
View File

@ -9,69 +9,154 @@
#include <proto/expansion.h>
#include <string.h>
#include "device.h"
#include "ata.h"
#include "device.h"
#include "idetask.h"
#include "newstyle.h"
#include "scsi.h"
#include "td64.h"
#if DEBUG
#include <clib/debug_protos.h>
#endif
void handle_scsi_command(struct IOStdReq *ioreq) {
/**
* handle_scsi_command
*
* Handle SCSI Direct commands
* @param ioreq IO Request
*/
static void handle_scsi_command(struct IOStdReq *ioreq) {
struct SCSICmd *scsi_command = ioreq->io_Data;
char *inquiry_data;
struct SCSI_CDB_6 *cdb_6;
struct SCSI_CDB_10 *cdb_10;
struct IDEUnit *unit = (struct IDEUnit *)ioreq->io_Unit;
APTR data = (APTR)scsi_command->scsi_Data;
APTR command = (APTR)scsi_command->scsi_Command;
ULONG lba;
UWORD count;
UBYTE error = 0;
#if DEBUG >= 2
KPrintF("Command %04x%04x\n",*scsi_command->scsi_Command);
#endif
switch (scsi_command->scsi_Command[0]) {
case SCSICMD_TEST_UNIT_READY:
ioreq->io_Error = 0;
scsi_command->scsi_Actual = 0;
error = 0;
break;
case SCSICMD_INQUIRY:
inquiry_data = (char *)scsi_command->scsi_Data;
inquiry_data[0] = 0;
inquiry_data[1] = 0;
inquiry_data[2] = 0;
inquiry_data[3] = 2;
inquiry_data[4] = 44-4;
inquiry_data[6] = 0;
inquiry_data[7] = 0;
((struct SCSI_Inquiry *)data)->peripheral_type = 0;
((struct SCSI_Inquiry *)data)->removable_media = 0;
((struct SCSI_Inquiry *)data)->version = 0;
((struct SCSI_Inquiry *)data)->response_format = 2;
((struct SCSI_Inquiry *)data)->additional_length = (sizeof(struct SCSI_Inquiry) - 4);
UWORD *identity = AllocMem(512,MEMF_CLEAR|MEMF_ANY);
if (!identity) {
ioreq->io_Error = TDERR_NotSpecified;
error = HFERR_BadStatus;
break;
}
if (!(ata_identify((struct IDEUnit *)ioreq->io_Unit,identity))) {
ioreq->io_Error = TDERR_NotSpecified;
if (!(ata_identify(unit,identity))) {
error = HFERR_BadStatus;
break;
}
CopyMem(&identity[ata_identify_model],&inquiry_data[8],24);
CopyMem(&identity[ata_identify_fw_rev],&inquiry_data[32],4);
CopyMem(&identity[ata_identify_serial],&inquiry_data[36],8);
CopyMem(&identity[ata_identify_model],&((struct SCSI_Inquiry *)data)->vendor,24);
CopyMem(&identity[ata_identify_fw_rev],&((struct SCSI_Inquiry *)data)->revision,4);
CopyMem(&identity[ata_identify_serial],&((struct SCSI_Inquiry *)data)->serial,8);
FreeMem(identity,512);
scsi_command->scsi_SenseActual = 0;
scsi_command->scsi_Actual = scsi_command->scsi_Length;
scsi_command->scsi_CmdActual = scsi_command->scsi_CmdLength;
ioreq->io_Error = 0;
error = 0;
break;
case SCSICMD_READ_CAPACITY_10:
if (data == NULL) {
error = IOERR_BADADDRESS;
break;
}
((struct SCSI_CAPACITY_10 *)data)->lba = (unit->sectorsPerTrack * unit->cylinders * unit->heads);
((struct SCSI_CAPACITY_10 *)data)->block_size = unit->blockSize;
scsi_command->scsi_Actual = 8;
error = 0;
break;
case SCSICMD_READ_6:
if (data == NULL) {
error = IOERR_BADADDRESS;
break;
}
cdb_6 = (struct SCSI_CDB_6 *)command;
lba = (((cdb_6->lba_high & 0x1F) << 16) | cdb_6->lba_mid << 8 | cdb_6->lba_low);
count = cdb_6->length;
error = ata_read(data,lba,count,&scsi_command->scsi_Actual,unit);
break;
case SCSICMD_READ_10:
if (data == NULL) {
error = IOERR_BADADDRESS;
break;
}
cdb_10 = (struct SCSI_CDB_10 *)command;
lba = cdb_10->lba;
count = cdb_10->length;
error = ata_read(data,lba,count,&scsi_command->scsi_Actual,unit);
break;
case SCSICMD_WRITE_6:
if (data == NULL) {
error = IOERR_BADADDRESS;
break;
}
cdb_6 = (struct SCSI_CDB_6 *)command;
lba = (((cdb_6->lba_high & 0x1F) << 16) | cdb_6->lba_mid << 8 | cdb_6->lba_low);
count = cdb_6->length;
error = ata_write(data,lba,count,&scsi_command->scsi_Actual,unit);
break;
case SCSICMD_WRITE_10:
if (data == NULL) {
error = IOERR_BADADDRESS;
break;
}
cdb_10 = (struct SCSI_CDB_10 *)command;
lba = cdb_10->lba;
count = cdb_10->length;
error = ata_write(data,lba,count,&scsi_command->scsi_Actual,unit);
break;
default:
ioreq->io_Error = TDERR_NotSpecified;
error = HFERR_BadStatus;
break;
}
ioreq->io_Error = error;
scsi_command->scsi_CmdActual = scsi_command->scsi_CmdLength;
scsi_command->scsi_SenseActual = 0;
}
/**
* ide_task
*
* This is a task to complete IO Requests for all units
* Requests are sent here from begin_io via the dev->TaskMP Message port
*/
void ide_task () {
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
struct Task *task = FindTask(NULL);
struct MsgPort *mp;
struct IOStdReq *ioreq;
struct IDEUnit *unit;
UWORD blocksize = 512;
ULONG lba = 0;
ULONG count = 0;
UWORD blocksize;
ULONG lba;
ULONG count;
#if DEBUG >= 1
KPrintF("Task waiting for init\n");
#endif
@ -79,8 +164,9 @@ void ide_task () {
struct DeviceBase *dev = (struct DeviceBase *)task->tc_UserData;
// Create the MessagePort used to send us requests
if ((mp = CreatePort(NULL,0)) == NULL) {
dev->Task = NULL;
dev->Task = NULL; // Failed to create MP, let the device know
RemTask(NULL);
Wait(0);
}
@ -92,42 +178,54 @@ void ide_task () {
#if DEBUG >= 2
KPrintF("WaitPort()\n");
#endif
Wait(1 << mp->mp_SigBit);
Wait(1 << mp->mp_SigBit); // Wait for an IORequest to show up
while ((ioreq = (struct IOStdReq *)GetMsg(mp))) {
unit = (struct IDEUnit *)ioreq->io_Unit;
switch (ioreq->io_Command) {
case CMD_READ:
#if DEBUG >= 2
KPrintF("CMD_READ\n");
#endif
ioreq->io_Actual = 0;
#if DEBUG >= 2
KPrintF("Offset: %04x%04x Size:%04x%04x\n", ioreq->io_Offset,ioreq->io_Length);
#endif
case TD_READ64:
case NSCMD_TD_READ64:
blocksize = ((struct IDEUnit *)ioreq->io_Unit)->blockSize;
lba = (((long long)ioreq->io_Actual << 32 | ioreq->io_Offset) / (UWORD)blocksize);
#if DEBUG >= 2
KPrintF("LBA: %04x%04x\n", lba);
#endif
lba = (((long long)ioreq->io_Actual << 32 | ioreq->io_Offset) / (UWORD)blocksize);
count = (ioreq->io_Length/(UWORD)blocksize);
ioreq->io_Error = ata_read(ioreq->io_Data, lba, count, &ioreq->io_Actual, unit);
break;
case CMD_WRITE:
ioreq->io_Actual = 0;
case TD_WRITE64:
case TD_FORMAT64:
case NSCMD_TD_WRITE64:
case NSCMD_TD_FORMAT64:
blocksize = ((struct IDEUnit *)ioreq->io_Unit)->blockSize;
lba = (((long long)ioreq->io_Actual << 32 | ioreq->io_Offset) / (UWORD)blocksize);
count = (ioreq->io_Length/(UWORD)blocksize);
ioreq->io_Error = ata_write(ioreq->io_Data, lba, count, &ioreq->io_Actual, unit);
ioreq->io_Error = 0;
break;
case HD_SCSICMD:
handle_scsi_command(ioreq);
break;
/* CMD_DIE: Shut down this task and clean up */
case CMD_DIE:
#if DEBUG > 0
KPrintF("CMD_DIE: Shutting down IDE Task\n");
#endif
DeletePort(mp);
dev->TaskMP = NULL;
dev->Task = NULL;
ReplyMsg(&ioreq->io_Message);
RemTask(NULL);
Wait(0);
default:
// Unknown commands.
ioreq->io_Error = IOERR_NOCMD;
ioreq->io_Actual = 0;
break;

View File

@ -1,8 +1,10 @@
#include <stdbool.h>
#include "device.h"
#include <stdbool.h>
#define TASK_NAME "idetask"
#define TASK_PRIORITY 0
#define TASK_STACK_SIZE 65535
#define CMD_DIE CMD_NONSTD+1
void ide_task();

BIN
liv2ride

Binary file not shown.

86
newstyle.h Normal file
View File

@ -0,0 +1,86 @@
#ifndef DEVICES_NEWSTYLE_H
#define DEVICES_NEWSTYLE_H
/*------------------------------------------------------------------------*/
/*
* $Id: newstyle.h 1.1 1997/05/15 18:53:15 heinz Exp $
*
* Support header for the New Style Device standard
*
* (C)1996-1997 by Amiga International, Inc.
*
*/
/*------------------------------------------------------------------------*/
/*
* At the moment there is just a single new style general command:
*/
#define NSCMD_DEVICEQUERY 0x4000
struct NSDeviceQueryResult {
/*
** Standard information, must be reset for every query
*/
ULONG DevQueryFormat; /* this is type 0 */
ULONG SizeAvailable; /* bytes available */
/*
** Common information (READ ONLY!)
*/
UWORD DeviceType; /* what the device does */
UWORD DeviceSubType; /* depends on the main type */
UWORD *SupportedCommands; /* 0 terminated list of cmd's */
/* May be extended in the future! Check SizeAvailable! */
};
#define NSDEVTYPE_UNKNOWN 0 /* No suitable category, anything */
#define NSDEVTYPE_GAMEPORT 1 /* like gameport.device */
#define NSDEVTYPE_TIMER 2 /* like timer.device */
#define NSDEVTYPE_KEYBOARD 3 /* like keyboard.device */
#define NSDEVTYPE_INPUT 4 /* like input.device */
#define NSDEVTYPE_TRACKDISK 5 /* like trackdisk.device */
#define NSDEVTYPE_CONSOLE 6 /* like console.device */
#define NSDEVTYPE_SANA2 7 /* A >=SANA2R2 networking device */
#define NSDEVTYPE_AUDIO 8 /* like audio.device */
#define NSDEVTYPE_CLIPBOARD 9 /* like clipboard.device */
#define NSDEVTYPE_PRINTER 10 /* like printer.device */
#define NSDEVTYPE_SERIAL 11 /* like serial.device */
#define NSDEVTYPE_PARALLEL 12 /* like parallel.device */
/*------------------------------------------------------------------------*/
/* The following defines should really be part of device specific
* includes. So we protect them from being redefined.
*/
#ifndef NSCMD_TD_READ64
/*
* An early new style trackdisk like device can also return this
* new identifier for TD_GETDRIVETYPE. This should no longer
* be the case though for newly written or updated NSD devices.
* This identifier is ***OBSOLETE***
*/
#define DRIVE_NEWSTYLE (0x4E535459L) /* 'NSTY' */
/*
* At the moment, only four new style commands in the device
* specific range and their ETD counterparts may be implemented.
*/
#define NSCMD_TD_READ64 0xC000
#define NSCMD_TD_WRITE64 0xC001
#define NSCMD_TD_SEEK64 0xC002
#define NSCMD_TD_FORMAT64 0xC003
#define NSCMD_ETD_READ64 0xE000
#define NSCMD_ETD_WRITE64 0xE001
#define NSCMD_ETD_SEEK64 0xE002
#define NSCMD_ETD_FORMAT64 0xE003
#endif /* NSCMD_TD_READ64 */
/*------------------------------------------------------------------------*/
#endif /* DEVICES_NEWSTYLE_H */

190
scsi.h
View File

@ -1,146 +1,44 @@
enum scsi_commands {
SCSICMD_TEST_UNIT_READY = 0x00,
SCSICMD_REWIND = 0x01,
SCSICMD_REQUEST_SENSE = 0x03,
SCSICMD_FORMAT = 0x04,
SCSICMD_READ_BLOCK_LIMITS = 0x05,
SCSICMD_REASSIGN_BLOCKS = 0x07,
SCSICMD_INITIALIZE_ELEMENT_STATUS = 0x07,
SCSICMD_READ_6 = 0x08,
SCSICMD_WRITE_6 = 0x0A,
SCSICMD_SEEK_6 = 0x0B,
SCSICMD_READ_REVERSE_6 = 0x0F,
SCSICMD_WRITE_FILEMARKS_6 = 0x10,
SCSICMD_SPACE_6 = 0x11,
SCSICMD_INQUIRY = 0x12,
SCSICMD_VERIFY_6 = 0x13,
SCSICMD_RECOVER_BUFFERED_DATA = 0x14,
SCSICMD_MODE_SELECT_6 = 0x15,
SCSICMD_RESERVE_6 = 0x16,
SCSICMD_RELEASE_6 = 0x17,
SCSICMD_COPY = 0x18,
SCSICMD_ERASE_6 = 0x19,
SCSICMD_MODE_SENSE_6 = 0x1A,
SCSICMD_START_STOP_UNIT = 0x1B,
SCSICMD_LOAD_UNLOAD = 0x1B,
SCSICMD_RECEIVE_DIAGNOSTIC_RESULTS = 0x1C,
SCSICMD_SEND_DIAGNOSTIC = 0x1D,
SCSICMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
SCSICMD_READ_FORMAT_CAPACITIES = 0x23,
SCSICMD_READ_CAPACITY_10 = 0x25,
SCSICMD_READ_10 = 0x28,
SCSICMD_READ_GENERATION = 0x29,
SCSICMD_WRITE_10 = 0x2A,
SCSICMD_SEEK_10 = 0x2B,
SCSICMD_LOCATE_10 = 0x2B,
SCSICMD_ERASE_10 = 0x2C,
SCSICMD_READ_UPDATED_BLOCK = 0x2D,
SCSICMD_WRITE_AND_VERIFY_10 = 0x2E,
SCSICMD_VERIFY_10 = 0x2F,
SCSICMD_SET_LIMITS_10 = 0x33,
SCSICMD_PREFETCH_10 = 0x34,
SCSICMD_READ_POSITION = 0x34,
SCSICMD_SYNCHRONIZE_CACHE_10 = 0x35,
SCSICMD_LOCK_UNLOCK_CACHE_10 = 0x36,
SCSICMD_READ_DEFECT_DATA_10 = 0x37,
SCSICMD_INITIALIZE_ELEMENT_STATUS_WITH_RANGE = 0x37,
SCSICMD_MEDIUM_SCAN = 0x38,
SCSICMD_COMPARE = 0x39,
SCSICMD_COPY_AND_VERIFY = 0x3A,
SCSICMD_WRITE_BUFFER = 0x3B,
SCSICMD_READ_BUFFER = 0x3C,
SCSICMD_UPDATE_BLOCK = 0x3D,
SCSICMD_READ_LONG_10 = 0x3E,
SCSICMD_WRITE_LONG_10 = 0x3F,
SCSICMD_CHANGE_DEFINITION = 0x40,
SCSICMD_WRITE_SAME_10 = 0x41,
SCSICMD_UNMAP = 0x42,
SCSICMD_READ_TOC_PMA_ATIP = 0x43,
SCSICMD_REPORT_DENSITY_SUPPORT = 0x44,
SCSICMD_PLAY_AUDIO_10 = 0x45,
SCSICMD_GET_CONFIGURATION = 0x46,
SCSICMD_PLAY_AUDIO_MSF = 0x47,
SCSICMD_SANITIZE = 0x48,
SCSICMD_GET_EVENT_STATUS_NOTIFICATION = 0x4A,
SCSICMD_PAUSE_RESUME = 0x4B,
SCSICMD_LOG_SELECT = 0x4C,
SCSICMD_LOG_SENSE = 0x4D,
SCSICMD_XDWRITE_10 = 0x50,
SCSICMD_XPWRITE_10 = 0x51,
SCSICMD_READ_DISC_INFORMATION = 0x51,
SCSICMD_XDREAD_10 = 0x52,
SCSICMD_XDWRITEREAD_10 = 0x53,
SCSICMD_SEND_OPC_INFORMATION = 0x54,
SCSICMD_MODE_SELECT_10 = 0x55,
SCSICMD_RESERVE_10 = 0x56,
SCSICMD_RELEASE_10 = 0x57,
SCSICMD_REPAIR_TRACK = 0x58,
SCSICMD_MODE_SENSE_10 = 0x5A,
SCSICMD_CLOSE_TRACK_SESSION = 0x5B,
SCSICMD_READ_BUFFER_CAPACITY = 0x5C,
SCSICMD_SEND_CUE_SHEET = 0x5D,
SCSICMD_PERSISTENT_RESERVE_IN = 0x5E,
SCSICMD_PERSISTENT_RESERVE_OUT = 0x5F,
SCSICMD_EXTENDED_CDB = 0x7E,
SCSICMD_VARIABLELENGTH_CDB = 0x7F,
SCSICMD_XDWRITE_EXTENDED_16 = 0x80,
SCSICMD_WRITE_FILEMARKS_16 = 0x80,
SCSICMD_READ_REVERSE_16 = 0x81,
SCSICMD_3RDPARTY_COPY_OUT_CMDS = 0x83,
SCSICMD_3RDPARTY_COPY_IN_CMDS = 0x84,
SCSICMD_ATA_PASSTHROUGH_16 = 0x85,
SCSICMD_ACCESS_CONTROL_IN = 0x86,
SCSICMD_ACCESS_CONTROL_OUT = 0x87,
SCSICMD_READ_16 = 0x88,
SCSICMD_COMPARE_AND_WRITE = 0x89,
SCSICMD_WRITE_16 = 0x8A,
SCSICMD_ORWRITE = 0x8B,
SCSICMD_READ_ATTRIBUTE = 0x8C,
SCSICMD_WRITE_ATTRIBUTE = 0x8D,
SCSICMD_WRITE_AND_VERIFY_16 = 0x8E,
SCSICMD_VERIFY_16 = 0x8F,
SCSICMD_PREFETCH_16 = 0x90,
SCSICMD_SYNCHRONIZE_CACHE_16 = 0x91,
SCSICMD_SPACE_16 = 0x91,
SCSICMD_LOCK_UNLOCK_CACHE_16 = 0x92,
SCSICMD_LOCATE_16 = 0x92,
SCSICMD_WRITE_SAME_16 = 0x93,
SCSICMD_ERASE_16 = 0x93,
SCSICMD_SERVICE_ACTION_BIDIRECTIONAL = 0x9D,
SCSICMD_SERVICE_ACTION_IN_16 = 0x9E,
SCSICMD_SERVICE_ACTION_OUT_16 = 0x9F,
SCSICMD_REPORT_LUNS = 0xA0,
SCSICMD_ATA_PASSTHROUGH_12 = 0xA1,
SCSICMD_SECURITY_PROTOCOL_IN = 0xA2,
SCSICMD_MAINTENANCE_IN = 0xA3,
SCSICMD_MAINTENANCE_OUT = 0xA4,
SCSICMD_REPORT_KEY = 0xA4,
SCSICMD_MOVE_MEDIUM = 0xA5,
SCSICMD_PLAY_AUDIO_12 = 0xA5,
SCSICMD_EXCHANGE_MEDIUM = 0xA6,
SCSICMD_MOVE_MEDIUM_ATTACHED = 0xA7,
SCSICMD_READ_12 = 0xA8,
SCSICMD_SERVICE_ACTION_OUT_12 = 0xA9,
SCSICMD_WRITE_12 = 0xAA,
SCSICMD_SERVICE_ACTION_IN_12 = 0xAB,
SCSICMD_ERASE_12 = 0xAC,
SCSICMD_READ_DVD_STRUCTURE = 0xAD,
SCSICMD_WRITE_AND_VERIFY_12 = 0xAE,
SCSICMD_VERIFY_12 = 0xAF,
SCSICMD_SEARCH_DATA_HIGH_12 = 0xB0,
SCSICMD_SEARCH_DATA_EQUAL_12 = 0xB1,
SCSICMD_SEARCH_DATA_LOW_12 = 0xB2,
SCSICMD_SET_LIMITS_12 = 0xB3,
SCSICMD_READ_ELEMENT_STATUS_ATTACHED = 0xB4,
SCSICMD_SECURITY_PROTOCOL_OUT = 0xB5,
SCSICMD_SEND_VOLUME_TAG = 0xB6,
SCSICMD_READ_DEFECT_DATA_12 = 0xB7,
SCSICMD_READ_ELEMENT_STATUS = 0xB8,
SCSICMD_READ_CD_MSF = 0xB9,
SCSICMD_REDUNDANCY_GROUP_IN = 0xBA,
SCSICMD_REDUNDANCY_GROUP_OUT = 0xBB,
SCSICMD_SPARE_IN = 0xBC,
SCSICMD_SPARE_OUT = 0xBD,
SCSICMD_VOLUME_SET_IN = 0xBE,
SCSICMD_VOLUME_SET_OUT = 0xBF,
};
#define SCSICMD_TEST_UNIT_READY 0x00
#define SCSICMD_READ_6 0x08
#define SCSICMD_WRITE_6 0x0A
#define SCSICMD_INQUIRY 0x12
#define SCSICMD_READ_CAPACITY_10 0x25
#define SCSICMD_READ_10 0x28
#define SCSICMD_WRITE_10 0x2A
struct __attribute__((packed)) SCSI_Inquiry {
UBYTE peripheral_type;
UBYTE removable_media;
UBYTE version;
UBYTE response_format;
UBYTE additional_length;
UBYTE flags[3];
UBYTE vendor[8];
UBYTE product[16];
UBYTE revision[4];
UBYTE serial[8];
};
struct __attribute__((packed)) SCSI_CDB_6 {
UBYTE operation;
UBYTE lba_high;
UBYTE lba_mid;
UBYTE lba_low;
UBYTE length;
UBYTE control;
};
struct __attribute__((packed)) SCSI_CDB_10 {
UBYTE operation;
UBYTE flags;
ULONG lba;
UBYTE group;
UWORD length;
UBYTE control;
};
struct __attribute__((packed)) SCSI_CAPACITY_10 {
ULONG lba;
ULONG block_size;
};

4
td64.h Normal file
View File

@ -0,0 +1,4 @@
#define TD_READ64 24
#define TD_WRITE64 25
#define TD_SEEK64 26
#define TD_FORMAT64 27