📄 scsi.c
字号:
* 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; sc->sc_attached[ui->ui_slave] = 1; /* * Initialize iostat sec/word transfer rate * for each disk/cdrom. * RZ22 1.0 / (60 * 33 * 256) (max data per one revolution) * RZ23 1.0 / (60 * 33 * 256) (max data per one revolution) * RZ55 1.0 / (60 * 36 * 256) (max data per one revolution) * RRD40 176.4 Kilobytes/second from spec */ if (ui->ui_dk >= 0) { sc->sc_dkn[ui->ui_slave] = ui->ui_dk;#ifdef NOWAY if (sc->sc_devtyp[ui->ui_slave] == RZ22) dk_mspw[ui->ui_dk] = 0.000002; else if (sc->sc_devtyp[ui->ui_slave] == RZ23) dk_mspw[ui->ui_dk] = 0.000002; else if (sc->sc_devtyp[ui->ui_slave] == RZ55) dk_mspw[ui->ui_dk] = 0.0000018; else if (sc->sc_devtyp[ui->ui_slave] == RRD40) dk_mspw[ui->ui_dk] = 0.0000113; else { sc->sc_dkn[ui->ui_slave] = -1; dk_mspw[ui->ui_dk] = 0.0;#endif NOWAY } else { sc->sc_dkn[ui->ui_slave] = -1; }#ifdef mips /* * This flag means that the drive is alive. */ dk_mspw[ui->ui_dk] = 1;#endif mips /* 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 = splbio(); 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; } /* end if alive */ splx(s); return(alive);}int sz_bp_pf = 0;/****************************************************************** * * Name: sz_bldpkt * * Abstract: Build a packet that is then passed one byte at a time * to the SCSI device. * * Inputs: * sc Pointer to softc structure for controller. * targid Target. * cmd The SCSI command to build. * addr The logical block address. * count The number of blocks. * * Outputs: None. * * Return values: None. * ******************************************************************/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 scsi_devtab *sdp; struct buf *bp = sc->sc_bp[targid]; /* get our bp filled in sz_start */ 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; 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 */ sdp = (struct scsi_devtab *)sc->sc_devtab[targid]; /* * 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; PRINTD(targid, 0x20, ("sz_bldpkt: command = 0x%x\n", cmd)); /* build the comand packet */ bzero((char *)&sc->sz_dat[targid], sizeof(sc->sz_dat[targid])); 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; /* * we don't have to convert the btye * count to blocks */ sc->sz_t_read.xferlen2 = LTOB( count, 2); sc->sz_t_read.xferlen1 = LTOB( count, 1); sc->sz_t_read.xferlen0 = LTOB( count, 0); } } /* * well we have a option table but this density * struct is not valid.... We must do something * but is it QIC 9trk 8mm etc... */ else { /* ERRLOG_MARK */ cprintf("scsi OPTTABLE off id = %X\n", targid); sc->sz_t_read.fixed = 0; sc->sz_t_read.xferlen2 = LTOB( count, 2); sc->sz_t_read.xferlen1 = LTOB( count, 1); sc->sz_t_read.xferlen0 = LTOB( count, 0); } /* end of if tape option table */ } /* * There is no option table... The default is * a normal tape drive...... */ else{ sc->sz_t_read.fixed = 0; /* only records */ sc->sz_t_read.xferlen2 = LTOB(count,2); sc->sz_t_read.xferlen1 = LTOB(count,1); sc->sz_t_read.xferlen0 = LTOB(count,0); } /* end of if tape */ } else { /* DISK r/w */ sc->sz_d_read.lbaddr2 = LTOB(addr,2); sc->sz_d_read.lbaddr1 = LTOB(addr,1); sc->sz_d_read.lbaddr0 = LTOB(addr,0); sc->sz_d_read.xferlen = LTOB(count/512,0); } break; case SZ_READ_10: case SZ_WRITE_10: { int blocks = (count / 512); sc->sz_d_rw10.lbaddr3 = LTOB(addr, 3); sc->sz_d_rw10.lbaddr2 = LTOB(addr, 2); sc->sz_d_rw10.lbaddr1 = LTOB(addr, 1); sc->sz_d_rw10.lbaddr0 = LTOB(addr, 0); sc->sz_d_rw10.xferlen1 = LTOB(blocks, 1); sc->sz_d_rw10.xferlen0 = LTOB(blocks, 0); break; } case SZ_FORMAT: fp = (struct format_params *) sc->sc_rzparams[targid]; if(fp->fp_defects == VENDOR_DEFECTS) { sc->sz_d_fu.fmtdat = 1; sc->sz_d_fu.cmplst = 1; } else if(fp->fp_defects == KNOWN_DEFECTS) { sc->sz_d_fu.fmtdat = 1; sc->sz_d_fu.cmplst = 0; } else if(fp->fp_defects == NO_DEFECTS) { sc->sz_d_fu.fmtdat = 0; sc->sz_d_fu.cmplst = 0; } sc->sz_d_fu.dlf = fp->fp_format; sc->sz_d_fu.pattern = fp->fp_pattern; sc->sz_d_fu.interleave1 = LTOB(fp->fp_interleave,1); sc->sz_d_fu.interleave0 = LTOB(fp->fp_interleave,0); break; case SZ_REASSIGN: break; case SZ_RDD: rdp = (struct read_defect_params *) sc->sc_rzparams[targid]; sc->sz_d_rdd.m = 1; sc->sz_d_rdd.g = 1; sc->sz_d_rdd.dlf = rdp->rdp_format; sc->sz_d_rdd.alclen1 = LTOB(rdp->rdp_alclen,1); sc->sz_d_rdd.alclen0 = LTOB(rdp->rdp_alclen,0); break; case SZ_VFY_DATA: vp = (struct verify_params *) sc->sc_rzparams[targid]; sc->sz_d_vd.reladr = 0; sc->sz_d_vd.bytchk = 0; sc->sz_d_vd.lbaddr3 = LTOB(vp->vp_lbn,3); sc->sz_d_vd.lbaddr2 = LTOB(vp->vp_lbn,2); sc->sz_d_vd.lbaddr1 = LTOB(vp->vp_lbn,1); sc->sz_d_vd.lbaddr0 = LTOB(vp->vp_lbn,0); sc->sz_d_vd.verflen1 = LTOB(vp->vp_length,1); sc->sz_d_vd.verflen0 = LTOB(vp->vp_length,0); break; case SZ_READL: case SZ_WRITEL: iox = (struct io_uxfer *) sc->sc_rzparams[targid]; prwl = (struct sz_rwl_cm *) &(iox->io_cdb[1]); sc->sz_rwl.reladr = prwl->reladr; sc->sz_rwl.lun = prwl->lun; sc->sz_rwl.phad = prwl->phad; sc->sz_rwl.lbaddr3 = prwl->lbaddr3; sc->sz_rwl.lbaddr2 = prwl->lbaddr2; sc->sz_rwl.lbaddr1 = prwl->lbaddr1; sc->sz_rwl.lbaddr0 = prwl->lbaddr0; sc->sz_rwl.dspec = prwl->dspec; break; case SZ_RQSNS: /* * 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 */ if (sc->sc_devtyp[targid] & SZ_TAPE) { todp = (struct tape_opt_tab *)sdp->opt_tab; /* * lets see if the request sense is valid */ if( todp->opt_flags & RSNS_ALLOCL_VAL){ /* * is the request size larger then storage */ if( todp->rsns_allocl > sizeof( struct sz_exsns_dt)){ /* * truncate the size */ sc->sz_rqsns.alclen = sizeof(struct sz_exsns_dt); } else { sc->sz_rqsns.alclen = todp->rsns_allocl; } } /* * we have an option table but they never validated * the request sense size default it.... */ else { sc->sz_rqsns.alclen = SZ_RQSNS_LEN; } } else { /* must be disk */ dodp = (struct disk_opt_tab *)sdp->opt_tab; /* * lets see if the request sense is valid
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -