📄 scsi.c
字号:
* NOTE: This table must be updated for any new additional commands added. */short sz_timetable[SZ_TIMETBL_SZ] = { 2, /* SZ_TUR 0x00 */ 10, /* SZ_REWIND 0x01 */ 0, /* unused 0x02 */ 2, /* SZ_RQSNS 0x03 */ 120, /* SZ_FORMAT 0x04 */ 2, /* SZ_RBL 0x05 */ 0, /* unused 0x06 */ 2, /* SZ_REASSIGN 0x07 */ 2, /* SZ_READ 0x08 */ 0, /* unused 0x09 */ 2, /* SZ_WRITE 0x0a */ 2, /* SZ_TRKSEL 0x0b */ 0, /* unused 0x0c */ 0, /* unused 0x0d */ 0, /* unused 0x0e */ 0, /* unused 0x0f */ 2, /* SZ_WFM 0x10 */ 120, /* SZ_SPACE 0x11 */ 2, /* SZ_INQ 0x12 */ 120, /* SZ_VFY 0x13 */ 2, /* SZ_RBD 0x14 */ 2, /* SZ_MODSEL 0x15 */ 2, /* SZ_RESUNIT 0x16 */ 2, /* SZ_RELUNIT 0x17 */ 0, /* unused 0x18 */ 120, /* SZ_ERASE 0x19 */ 2, /* SZ_MODSNS 0x1a */ 10, /* SZ_SSLU 0x1b */ 6, /* SZ_RCVDIAG 0x1c */ 6, /* SZ_SNDDIAG 0x1d */ 0, /* unused 0x1e */ 0, /* unused 0x1f */ 0, /* unused 0x20 */ 0, /* unused 0x21 */ 0, /* unused 0x22 */ 0, /* unused 0x23 */ 0, /* unused 0x24 */ 2, /* SZ_RDCAP 0x25 */ 0, /* unused 0x26 */ 0, /* unused 0x27 */ 3, /* SZ_READ_10 0x28 */ 0, /* unused 0x29 */ 3, /* SZ_WRITE_10 0x2a */ 0, /* unused 0x2b */ 0, /* unused 0x2c */ 0, /* unused 0x2d */ 0, /* unused 0x2e */ 12, /* SZ_VFY_DATA 0x2f */ 0, /* unused 0x30 */ 0, /* unused 0x31 */ 0, /* unused 0x32 */ 0, /* unused 0x33 */ 0, /* unused 0x34 */ 0, /* unused 0x35 */ 0, /* unused 0x36 */ 3, /* SZ_RDD 0x37 */ 0, /* unused 0x38 */ 0, /* unused 0x39 */ 0, /* unused 0x3a */ 0, /* unused 0x3b */ 0, /* unused 0x3c */ 0, /* unused 0x3d */ 0, /* unused 0x3e */ 0 /* unused 0x3f */};/* * The #define for SZDEBUG is in scsireg.h. */#ifdef SZDEBUGint szdebug = 0;#define printd if(szdebug)printf#define printd1 if (szdebug > 1) printf#define printd2 if (szdebug > 2) printf#define printd3 if (szdebug > 3) printf#define printd4 if (szdebug > 4) printf#define printd5 if (szdebug > 5) printf#define printd6 if (szdebug > 6) printf#endif SZDEBUG/* Declare the global debug variable for the scsi code. */long scsidebug = 0;/* * If SZDTMODE is defined then direct track mode can * be used to test multivolume dumps. This mode causes * EOM to occur at the end of the first track. * Set sz_direct_track_mode to one for direct track mode. */#define SZDTMODE#ifdef SZDTMODEint sz_direct_track_mode = 0; /* for testing multivolume dump */#endif SZDTMODE/* * Pointer to second sz_softc structure (ADB - debug aid). */struct sz_softc *sz_sc1_addr = (struct sz_softc *)sz_softc + 1;/* * These data structures and variables used by probe routines, * see scsi_5380.c and scsi_sii.c. */int szp_firstcall = 1;int szp_ntz;int szp_nrz;int szp_ncz;int szp_nrx;/* * These are default scsi_devtab entires for unknown devices. * There are here in case the user removes the "UNKNOWN" * entries from the scsi_devtab in scsi_data.c. */struct scsi_devtab szp_rz_udt = {"UNKNOWN", 7, DEV_RZxx, RZxx, sz_rzxx_sizes, 0, 0, SCSI_STARTUNIT|SCSI_MODSEL_PF|SCSI_NODBBR };struct scsi_devtab szp_tz_udt = {"UNKNOWN", 7, DEV_TZxx, TZxx, sz_null_sizes, 0, 0, SCSI_NODIAG};struct scsi_devtab szp_cz_udt = {"UNKNOWN", 7, DEV_RZxx, RZxx, sz_rrd40_sizes, 0, 0, SCSI_STARTUNIT|SCSI_MODSEL_PF|SCSI_NODBBR };/* * Compare strings (at most n bytes): s1>s2: >0 s1==s2: 0 s1<s2: <0 * NOTE: count must be accurate, because only one string is null terminated. */sz_strncmp(s1, s2, n)register char *s1, *s2;register n;{ while (--n >= 0 && *s1 == *s2++) if (*s1++ == '\0') return(0); return(n<0 ? 0 : *s1 - *--s2);}/* * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 */sz_strcmp(s1, s2)register char *s1, *s2;{ while (*s1 == *s2++) if (*s1++=='\0') return(0); return(*s1 - *--s2);}char sz_devname[SZ_DNSIZE+1];char sz_revlevel[SZ_REV_LEN+2];/* * * Name: szattach -Attach routine * * Abstract: This routine attaches a slave to the controller * by filling in the unit information structure * (a good deal of which is not used in this driver). * Also fills in the transfer rate for iostat if * the slave is a disk. Prints the device type * during autoconfigure. * * Inputs: * * ui Unit information structure pointer. * * Outputs: None. * * Return Values: None. * * Side Effects: None. * */szattach(ui) register struct uba_device *ui;{ register struct uba_ctlr *um; register struct sz_softc *sc; register struct scsi_devtab *sdp; int i; sc = &sz_softc[ui->ui_ctlr]; sdp = (struct scsi_devtab *)sc->sc_devtab[ui->ui_slave]; /* * NOTE: * This cannot happen, because the slave number for * the initator is never alive. We check anyway to be sure. */ if ((1 << ui->ui_slave) == sc->sc_sysid) return; ui->ui_flags = 0; um = ui->ui_mi; szutab[ui->ui_unit].b_actf = NULL; szutab[ui->ui_unit].b_actl = NULL; /* * Initialize iostat Msec/word transfer rate * for each disk/cdrom. * Values come from sz_dk_mspw table in scsi_data.c. */ if (ui->ui_dk >= 0) { sc->sc_dkn[ui->ui_slave] = ui->ui_dk; if (sdp->mspw != 0) { dk_mspw[ui->ui_dk] = sz_dk_mspw[sdp->mspw]; } else { sc->sc_dkn[ui->ui_slave] = -1; dk_mspw[ui->ui_dk] = 0.0; } } else { sc->sc_dkn[ui->ui_slave] = -1; } /* so device name appears after slave printout in autoconf */ printf(" (%s)", sc->sc_device[ui->ui_slave]); /* print vendor/product ID & rev level if non-DEC disk */ if ((sc->sc_devtyp[ui->ui_slave] == RZxx) || (sc->sc_devtyp[ui->ui_slave] == TZxx)) { for (i = 0; i < SZ_DNSIZE; i++) sz_devname[i] = sc->sc_devnam[ui->ui_slave][i]; sz_devname[SZ_DNSIZE] = 0; for (i = 0; i < SZ_REV_LEN; i++) sz_revlevel[i] = sc->sc_revlvl[ui->ui_slave][i]; sz_revlevel[SZ_REV_LEN] = 0; printf(" [ %s %s ]", sz_devname, sz_revlevel); }}/* * Name: szslave -Slave routine * * Abstract: This routines determines whether or not a slave * device is alive during autoconfigure. * * Inputs: * * ui Unit information structure pointer. * * Outputs: None. * * Return Values: * * 0 Slave is not alive. * * 1 Slave is alive. * * Side Effects: * IPL raised to 15. * */szslave(ui) register struct uba_device *ui;{ register struct uba_ctlr *um = szminfo[ui->ui_ctlr]; register struct sz_softc *sc; register int s = spl5(); int alive; alive = 1; while(1) { /* dead cntlr */ if (um->um_alive == 0) { alive = 0; break; } sc = &sz_softc[ui->ui_ctlr]; /* not target ID alive for this slave number */ if (sc->sc_alive[ui->ui_slave] == 0) { alive = 0; break; } /* see if correct device type, i.e., rz=disk or cdrom, tz=tape */ if ((strcmp("rz", ui->ui_devname) == 0) && (sc->sc_devtyp[ui->ui_slave] & SZ_DISK)) { break; } if ((strcmp("rz", ui->ui_devname) == 0) && (sc->sc_devtyp[ui->ui_slave] & SZ_CDROM)) { break; } if ((strcmp("tz", ui->ui_devname) == 0) && (sc->sc_devtyp[ui->ui_slave] & SZ_TAPE)) { break; } alive = 0; break; } if (alive) sc->sc_unit[ui->ui_slave] = ui->ui_unit; splx(s); return(alive);}/* * These are debug varaibles we want to keep. * They control some mode select bits. */int sz_bp_bufmode = 1;/* * * Name: sz_bldpkt -Build SCSI command routine * * Abstract: This routine builds the SCSI command packet of * the specified type and fills in all needed data. * The command is stored in the sz_softc structure * (sc_command) on a per target basis. * * Inputs: * * sc Pointer to controller's sz_softc structure. * targid Device SCSI target ID (0 - 7). * cmd SCSI command type (see scsivar.h). * addr Command address (such as disk block number). * count Command count (such as disk byte count). * * Outputs: * * sc_command Command packet. * sc_actcmd Command actually working on, i.e., current * command could be read actual command could be * a request sense. * * Return Values: * The routine returns values, but they are not used. * * Side Effects: * This routine could produce error messages and * undefined error conditions if called with * invalid inputs (eg, unsupported command type). * However, the routine is always called with * valid inputs. * */sz_bldpkt(sc, targid, cmd, addr, count)register struct sz_softc *sc;int targid;long cmd;daddr_t addr;long count;{ register u_char *byteptr; register int i; struct format_params *fp; struct read_defect_params *rdp; struct verify_params *vp; struct reassign_params *rp; struct mode_sel_sns_params *msp; struct io_uxfer *iox; struct sz_rwl_cm *prwl; struct scsi_devtab *sdp = sc->sc_devtab[targid]; struct buf *bp = sc->sc_bp[targid]; /* get our bp filled in sz_start */ int len; struct tape_opt_tab *todp; /* our tape option table pointer */ struct disk_opt_tab *dodp; /* our disk option table pointer */ struct tape_info *ddp; /* our density struct for tapes */ /* * Save cmd in sc_actcmd, so we know what command * we are really working on. For example, the current * command could be read, but the actual command * might be a request sense after the read. */ sc->sc_actcmd[targid] = cmd; /* * Get a byte address of the begining of sc->sz_cmd space, * and clear the data space */ byteptr = (u_char *)&sc->sz_command; for (i=0; i < SZ_MAX_CMD_LEN; i++) *byteptr++ = 0;#ifdef SZDEBUG if (sc->sc_flags[targid] & DEV_CSE) { printd1("sz_bldpkt: command = 0x%x\n", cmd); }#endif SZDEBUG /* build the comand packet */ switch (cmd) { case SZ_READ: case SZ_WRITE: case SZ_RBD: if (sc->sc_devtyp[targid] & SZ_TAPE) { /* TAPE r/w */ /* * Check to see if we have an option table * if we do use those values in the table to set * things up....... */ if( sdp->opt_tab != NULL ){ /* * we have an option table use it. * must cast the pointer */ todp = (struct tape_opt_tab *)sdp->opt_tab; /* * get our density struct pointer... */ ddp = &todp->tape_info[DENS_IDX( bp )]; /* * since this is just a simple read/write * all we have to do is determine if fixed * block add convert to bytes/block.. */ /* * lets see if this density selection is valid.. */ if( ddp->tape_flags & DENS_VAL ){ /* * this is valid lets get our stuff */ if( ddp->blk_size != NULL ){ /* * since blk size is non 0 * this must be a fixed block tape dens */ sc->sz_t_read.fixed = 1; /* fixed blocks */ /* * since fixed the count is in blocks not * bytes */ i = count/ddp->blk_size; sc->sz_t_read.xferlen2 = LTOB( i, 2); sc->sz_t_read.xferlen1 = LTOB( i, 1); sc->sz_t_read.xferlen0 = LTOB( i, 0); } else { sc->sz_t_read.fixed = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -