⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_amiga.c

📁 对SCSI设备 直接存取的通用库
💻 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 + -