scsitransp.c
来自「刻录光盘的程序」· C语言 代码 · 共 866 行 · 第 1/2 页
C
866 行
/* @(#)scsitransp.c 1.48 99/11/12 Copyright 1988,1995 J. Schilling */#ifndef lintstatic char sccsid[] = "@(#)scsitransp.c 1.48 99/11/12 Copyright 1988,1995 J. Schilling";#endif/* * SCSI user level command transport routines for * the SCSI general driver 'scg'. * * Warning: you may change this source, but if you do that * you need to change the _scg_version and _scg_auth* string below. * Choose your name instead of "schily" and make clear that the version * string is related to a modified source. * * Copyright (c) 1988,1995 J. Schilling *//* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include <mconfig.h>#ifdef HAVE_SYS_PARAM_H#include <sys/param.h> /* XXX nonportable to use u_char */#endif#include <stdio.h>#include <standard.h>#include <stdxlib.h>#include <unixstd.h>#include <errno.h>#include <timedefs.h>#include <sys/ioctl.h>#include <fctldefs.h>#include <scg/scgio.h>#include <scg/scsireg.h>#include <scg/scsitransp.h>#ifdef sun# define HAVE_SCG /* Currently only on SunOS/Solaris */#endif/* * Warning: you may change this source, but if you do that * you need to change the _scg_version and _scg_auth* string below. * You may not return "schily" for an SCG_AUTHOR request anymore. * Choose your name instead of "schily" and make clear that the version * string is related to a modified source. */LOCAL char _scg_version[] = "0.1"; /* The global libscg version */LOCAL char _scg_auth_schily[] = "schily"; /* The author for this module */#ifdef HAVE_SCGLOCAL char _scg_trans_version[] = "scg-1.48"; /* The version for /dev/scg */#endif#define DEFTIMEOUT 20 /* Default timeout for SCSI command transport *//* * Need to move this into an scg driver ioctl. *//*#define MAX_DMA_SUN4M (1024*1024)*/#define MAX_DMA_SUN4M (124*1024) /* Currently max working size *//*#define MAX_DMA_SUN4C (126*1024)*/#define MAX_DMA_SUN4C (124*1024) /* Currently max working size */#define MAX_DMA_SUN3 (63*1024)#define MAX_DMA_SUN386 (56*1024)#define MAX_DMA_OTHER (32*1024)#define ARCH_MASK 0xF0#define ARCH_SUN2 0x00#define ARCH_SUN3 0x10#define ARCH_SUN4 0x20#define ARCH_SUN386 0x30#define ARCH_SUN3X 0x40#define ARCH_SUN4C 0x50#define ARCH_SUN4E 0x60#define ARCH_SUN4M 0x70#define ARCH_SUNX 0x80EXPORT char *scg_version __PR((SCSI *scgp, int what));EXPORT char *scg__version __PR((SCSI *scgp, int what));EXPORT int scsi_open __PR((SCSI *scgp, char *device, int busno, int tgt, int tlun));EXPORT int scsi_close __PR((SCSI *scgp));LOCAL long scsi_maxdma __PR((SCSI *scgp));EXPORT BOOL scsi_havebus __PR((SCSI *scgp, int));EXPORT int scsi_fileno __PR((SCSI *scgp, int, int, int));EXPORT int scsi_initiator_id __PR((SCSI *scgp));EXPORT int scsi_isatapi __PR((SCSI *scgp));EXPORT int scsireset __PR((SCSI *scgp));EXPORT void *scsi_getbuf __PR((SCSI *scgp, long));EXPORT void scsi_freebuf __PR((SCSI *scgp));EXPORT long scsi_bufsize __PR((SCSI *scgp, long));EXPORT void scsi_setnonstderrs __PR((SCSI *scgp, const char **));EXPORT BOOL scsi_yes __PR((char *));#ifdef nononoLOCAL void scsi_sighandler __PR((int));#endifEXPORT int scsicmd __PR((SCSI *scgp));EXPORT int scsigetresid __PR((SCSI *scgp));LOCAL void scsitimes __PR((SCSI *scgp));LOCAL BOOL scsierr __PR((SCSI *scgp));LOCAL int scsicheckerr __PR((SCSI *scgp));EXPORT void scsiprinterr __PR((SCSI *scgp));EXPORT void scsiprintcdb __PR((SCSI *scgp));EXPORT void scsiprintwdata __PR((SCSI *scgp));EXPORT void scsiprintrdata __PR((SCSI *scgp));EXPORT void scsiprintresult __PR((SCSI *scgp));EXPORT void scsiprintstatus __PR((SCSI *scgp));EXPORT void scsiprbytes __PR((char *, unsigned char *, int));EXPORT void scsiprsense __PR((unsigned char *, int));EXPORT int scsi_sense_key __PR((SCSI *scgp));EXPORT int scsi_sense_code __PR((SCSI *scgp));EXPORT int scsi_sense_qual __PR((SCSI *scgp));EXPORT void scsiprintdev __PR((struct scsi_inquiry *));#ifdef HAVE_SCG# include <libport.h> /* Needed for gethostid() */#ifdef sun#ifdef HAVE_SUN_DKIO_H# include <sun/dkio.h># define dk_cinfo dk_conf# define dki_slave dkc_slave# define DKIO_GETCINFO DKIOCGCONF#endif#ifdef HAVE_SYS_DKIO_H# include <sys/dkio.h># define DKIO_GETCINFO DKIOCINFO#endif#define TARGET(slave) ((slave >> 3) & 07)#endif /* sun *//* * We are using a "real" /dev/scg? */# define scsi_send(scgp, f, cmdp) ioctl((f), SCGIO_CMD, (cmdp))# define MAX_SCG 16 /* Max # of SCSI controllers */struct scg_local { int scgfiles[MAX_SCG];};#define scglocal(p) ((struct scg_local *)((p)->local)) #define scgfiles(p) ((int *)((p)->local)) #else/* * We are emulating the functionality of /dev/scg? with the local * SCSI user land implementation. */# include "scsihack.c"#endif /* HAVE_SCG *//* * Return version information for the SCSI transport code. * This has been introduced to make it easier to trace down problems * in applications. * * If scgp is NULL, return general library version information. * If scgp is != NULL, return version information for the low level transport. */EXPORT char *scg_version(scgp, what) SCSI *scgp; int what;{ if (scgp == (SCSI *)0) { switch (what) { case SCG_VERSION: return (_scg_version); /* * If you changed this source, you are not allowed to * return "schily" for the SCG_AUTHOR request. */ case SCG_AUTHOR: return (_scg_auth_schily); case SCG_SCCS_ID: return (sccsid); default: return ((char *)0); } } return (scg__version(scgp, what));}#ifdef HAVE_SCG/* * Return version information for the low level SCSI transport code. * This has been introduced to make it easier to trace down problems * in applications. */EXPORT char *scg__version(scgp, what) SCSI *scgp; int what;{ if (scgp != (SCSI *)0) { switch (what) { case SCG_VERSION: return (_scg_trans_version); /* * If you changed this source, you are not allowed to * return "schily" for the SCG_AUTHOR request. */ case SCG_AUTHOR: return (_scg_auth_schily); case SCG_SCCS_ID: return (sccsid); } } return ((char *)0);}EXPORT intscsi_open(scgp, device, busno, tgt, tlun) SCSI *scgp; char *device; int busno; int tgt; int tlun;{ register int f; register int i; register int nopen = 0; char devname[32]; if (busno >= MAX_SCG) { errno = EINVAL; if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Illegal value for busno '%d'", busno); return (-1); } if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { errno = EINVAL; if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Open by 'devname' not supported on this OS"); return (-1); } if (scgp->local == NULL) { scgp->local = malloc(sizeof(struct scg_local)); if (scgp->local == NULL) { if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "No memory for scg_local"); return (0); } for (i=0; i < MAX_SCG; i++) { scgfiles(scgp)[i] = -1; } } for (i=0; i < MAX_SCG; i++) { sprintf(devname, "/dev/scg%d", i); f = open(devname, 2); if (f < 0) { if (errno != ENOENT && errno != ENXIO) { if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '%s'", devname); return (-1); } } else { nopen++; } scgfiles(scgp)[i] = f; } return (nopen);}EXPORT intscsi_close(scgp) SCSI *scgp;{ register int i; if (scgfiles(scgp) == NULL) return (-1); for (i=0; i < MAX_SCG; i++) { if (scgfiles(scgp)[i] >= 0) close(scgfiles(scgp)[i]); scgfiles(scgp)[i] = -1; } return (0);}LOCAL longscsi_maxdma(scgp) SCSI *scgp;{ long maxdma = 0L;#ifdef sun#if defined(__i386_) || defined(i386) return (MAX_DMA_SUN386);#else int cpu_type = gethostid() >> 24; switch (cpu_type & ARCH_MASK) { case ARCH_SUN4C: case ARCH_SUN4E: maxdma = MAX_DMA_SUN4C; break; case ARCH_SUN4M: case ARCH_SUNX: maxdma = MAX_DMA_SUN4M; break; default: maxdma = MAX_DMA_SUN3; }#endif /* sun */#else maxdma = MAX_DMA_OTHER;#endif#ifndef __SVR4 /* * SunOS 4.x allows esp hardware on VME boards and thus * limits DMA on esp to 64k-1 */ if (maxdma > MAX_DMA_SUN3) maxdma = MAX_DMA_SUN3;#endif return (maxdma);}EXPORTBOOL scsi_havebus(scgp, busno) SCSI *scgp; int busno;{ if (scgfiles(scgp) == NULL) return (FALSE); return (busno < 0 || busno >= MAX_SCG) ? FALSE : (scgfiles(scgp)[busno] >= 0);}EXPORTint scsi_fileno(scgp, busno, tgt, tlun) SCSI *scgp; int busno; int tgt; int tlun;{ if (scgfiles(scgp) == NULL) return (-1); return (busno < 0 || busno >= MAX_SCG) ? -1 : scgfiles(scgp)[busno];}EXPORT intscsi_initiator_id(scgp) SCSI *scgp;{ int f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun); int id = -1;#ifdef DKIO_GETCINFO struct dk_cinfo conf; if (ioctl(f, DKIO_GETCINFO, &conf) < 0) return (id); if (TARGET(conf.dki_slave) != -1) id = TARGET(conf.dki_slave);#endif return (id);}EXPORTint scsi_isatapi(scgp) SCSI *scgp;{ return (FALSE);}EXPORTint scsireset(scgp) SCSI *scgp;{ int f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun); return (ioctl(f, SCGIORESET, 0));}EXPORT void *scsi_getbuf(scgp, amt) SCSI *scgp; long amt;{ if (amt <= 0 || amt > scsi_maxdma(scgp)) return ((void *)0); scgp->bufbase = (void *)valloc((size_t)amt); return (scgp->bufbase);}EXPORT voidscsi_freebuf(scgp) SCSI *scgp;{ if (scgp->bufbase) free(scgp->bufbase); scgp->bufbase = NULL;}#endif /* HAVE_SCG */EXPORT longscsi_bufsize(scgp, amt) SCSI *scgp; long amt;{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?