📄 os_amiga.c
字号:
/* os_amiga -- system interface for AmigaDOS Copyright (C) 1996 Dieter Baron and Armin Obersteiner This file is part of libscsi, a library for direct scsi device access The authors can be contacted at <dillo@giga.or.at> <armin.obersteiner@giga.or.at> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <exec/types.h>#include <exec/io.h>#include <exec/memory.h>#include <devices/scsidisk.h>#include <libraries/dos.h>#include <proto/exec.h>#include <proto/dos.h>#include <errno.h>#include <scsi/scsi.h>#define DATABUFLEN (128*1024)#define MAXUNIT 7#define DEF_DEV "gvpscsi.device"#define MEM MEMF_24BITDMA#define SENSE SCSIF_AUTOSENSEstruct SCSICmd sc__req;SCSI *sc_open(char *device){ SCSI *scsi; struct MsgPort *mp; struct IOStdReq *io; UBYTE *scsidata; UBYTE *sensedata; char dev[256]; int unit=0; if(strstr(device,":")==NULL) { strcpy(dev,DEF_DEV); unit=atoi(strtok(device," \0")); } else { strcpy(dev,(char *)strtok(device,":")); if(strstr(dev,".")==NULL) strcat(dev,".device"); unit=atoi(strtok(NULL," \0")); } if(unit<0 || unit>MAXUNIT) unit=0; if((scsi=(SCSI *)AllocMem(sizeof(SCSI), MEM)) == NULL) return NULL; if((sensedata = AllocMem(sizeof(struct sc_sense_data), MEM)) == NULL) { FreeMem(scsi,sizeof(SCSI)); return NULL; } if((scsidata = AllocMem(DATABUFLEN, MEM)) == NULL) { FreeMem(sensedata,sizeof(struct sc_sense_data)); FreeMem(scsi,sizeof(SCSI)); return NULL; } if((mp = (struct MsgPort *)CreatePort(NULL, 0)) == NULL) { FreeMem(scsidata,DATABUFLEN); FreeMem(sensedata,sizeof(struct sc_sense_data)); FreeMem(scsi,sizeof(SCSI)); return NULL; } if((io = (struct IOStdReq *)CreateStdIO(mp)) == NULL) { DeletePort(mp); FreeMem(scsidata,DATABUFLEN); FreeMem(sensedata,sizeof(struct sc_sense_data)); FreeMem(scsi,sizeof(SCSI)); return NULL; } if(OpenDevice(dev,unit, (struct IORequest *)io, 0) == 0) { io->io_Command = HD_SCSICMD; io->io_Length = sizeof(struct SCSICmd); io->io_Data = (APTR)&sc__req; scsi->mp = mp; scsi->io = io; scsi->scsidata = scsidata; scsi->sensedata = sensedata; scsi->sense.status = scsi->sense.len = 0; scsi->timeout = 10000; return scsi; } else { DeleteStdIO(io); DeletePort(mp); FreeMem(scsidata,DATABUFLEN); FreeMem(sensedata,sizeof(struct sc_sense_data)); FreeMem(scsi,sizeof(SCSI)); return NULL; }}int sc_close(SCSI *s){ if(s!=NULL) { CloseDevice((struct IORequest *)s->io); DeleteStdIO(s->io); DeletePort(s->mp); FreeMem(s->scsidata,DATABUFLEN); FreeMem(s->sensedata,sizeof(struct sc_sense_data)); FreeMem(s,sizeof(SCSI)); return 0; } return -1;}int sc_send(SCSI *s, int direction, int cmdlen, char *cmd, int datalen, char *data){ int result; int copy=1; if(! (TypeOfMem(data) && MEM) ) { if(datalen>DATABUFLEN) { s->sense.status = -1; s->sense.len = 0; errno = ENOMEM; return -1; } else if(direction==SC_WRITE) CopyMem(data,s->scsidata,datalen); sc__req.scsi_Data = (UWORD *)(s->scsidata); } else { sc__req.scsi_Data = (UWORD *)data; copy=0; } sc__req.scsi_Length = datalen; sc__req.scsi_Actual = ((direction==SC_WRITE) ? datalen : 0); sc__req.scsi_Command = (UBYTE *)cmd; sc__req.scsi_CmdLength = cmdlen; switch (direction) { case SC_READ: sc__req.scsi_Flags = SCSIF_READ | SENSE; break; case SC_WRITE: sc__req.scsi_Flags = SCSIF_WRITE | SENSE; break; default: sc__req.scsi_Flags = SENSE; } sc__req.scsi_SenseData = (UBYTE *)(s->sensedata); sc__req.scsi_SenseLength = sizeof(struct sc_sense_data); sc__req.scsi_SenseActual = 0; DoIO((struct IORequest *)(s->io)); if(sc__req.scsi_Status || sc__req.scsi_SenseActual) { switch (sc__req.scsi_Status) { case 0: /* good */ case 4: /* condition met */ s->sense.status = 0; break; case 2: /* check condition */ s->sense.status = 3; break; case 8: /* busy */ s->sense.status = 2; break; default: s->sense.status = 5; } s->sense.len = sc__req.scsi_SenseActual; CopyMem(s->sensedata,&s->sense.data, sc__req.scsi_SenseActual); } if((direction==SC_READ) && copy) CopyMem(s->scsidata,data,datalen); return ((s->sense.status !=0 || (sc__req.scsi_SenseActual>3 && (sc__req.scsi_SenseData[2] & 0x0f))) ? -1 : (direction==SC_READ ? sc__req.scsi_Actual : 0));}int sc_set_timeout(SCSI *s, u_long timeout){ s->timeout = timeout; return 0;}void *sc_alloc(size_t size){ ULONG *data; if((data = (ULONG *)AllocVec(size, MEM)) == NULL) return NULL; else { return (void *)(data); }}void sc_free(void *mem){ ULONG *data=mem; FreeVec(data);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -