#include #include #include #include #include "send_scsi_cmd.h" extern WORD Send_SCSI_CMD( const STRPTR devicename, const ULONG devunit, const ULONG opendevflags, struct sizedbuffer * cmdbuffer, struct sizedbuffer * databuffer, struct sizedbuffer * sensebuffer, const UBYTE LUN, const UBYTE scsiflags) { struct IOStdReq * req; struct MsgPort * myport; WORD retval = -1; // Controllo di alcuni parametri di chiamata. if(!cmdbuffer || !databuffer || !sensebuffer) return -1; if((cmdbuffer->len != 6) && (cmdbuffer->len != 10) && (cmdbuffer->len != 12) && (cmdbuffer->len != 16)) return -1; if((scsiflags & SCSIF_AUTOSENSE) && sensebuffer->len < 18) return -1; if(sensebuffer->len > 254) sensebuffer->len = 254; // Tronca i sense buffer troppo lunghi. if(LUN > 7) return -1; /* Il controllo qui sopra presuppone un utilizzo della LUN in stile SCSI-2, che implica tra l'altro l'uso di un bus parallelo (SPI). */ if(myport=CreateMsgPort()) // Creazione message port per l'IO { if(req=CreateStdIO(myport)) // Creazione dell'IORequest (esteso) { UBYTE deverr; struct SCSICmd cmdstruct; // La struttura apposita. if(deverr=OpenDevice(devicename, devunit, (struct IORequest *)req, opendevflags)) { retval = (WORD)(req->io_Error<<8); // Per qualche motivo la periferica non è disponibile. } else { /* Assegnazione dei vari campi */ cmdstruct.scsi_Data = databuffer->buf; cmdstruct.scsi_Length = databuffer->len; cmdstruct.scsi_Command = cmdbuffer->buf; cmdstruct.scsi_CmdLength= cmdbuffer->len; cmdstruct.scsi_SenseData= sensebuffer->buf; cmdstruct.scsi_SenseLength= sensebuffer->len; cmdstruct.scsi_Flags = scsiflags; /* Azzeramento dei valori in uscita */ cmdstruct.scsi_Status = cmdstruct.scsi_Actual = 0; cmdstruct.scsi_CmdActual= cmdstruct.scsi_SenseActual = 0; if(LUN) { SET_LUN_ON_COMMAND(cmdstruct.scsi_Command, LUN); } /* Configurazione dell'IOStdReq . */ req->io_Length = sizeof(struct SCSICmd); req->io_Data = (APTR) &cmdstruct; req->io_Command = HD_SCSICMD; req->io_Flags = req->io_Actual = req->io_Offset = 0; /* Esecuzione del comando!! */ retval = DoIO((struct IORequest *)req); /* I valori in uscita: gli Actual .*/ cmdbuffer->actual = cmdstruct.scsi_CmdActual; sensebuffer->actual = cmdstruct.scsi_SenseActual; databuffer->actual = cmdstruct.scsi_Actual; retval = retval<<8 | cmdstruct.scsi_Status; CloseDevice((struct IORequest *)req); // Chiude il device. } DeleteStdIO(req); // Dealloca la struttura per l'IO } else retval = -1; DeleteMsgPort(myport); } return retval; }