📄 scsi-sun.c
字号:
#define STATUS_SCSI2 0x20#define STATUS_INTERMEDIATE_MET 0x14#define STATUS_RESERVATION_CONFLICT 0x18#define STATUS_TERMINATED 0x22#define STATUS_QFULL 0x28#define STATUS_ACA_ACTIVE 0x30#endifLOCAL intscsi_uopen(scgp, device, busno, tgt, tlun) SCSI *scgp; char *device; int busno; int tgt; int tlun;{ register int f; register int b; register int t; register int l; register int nopen = 0; char devname[32]; if (scgp->overbose) error("Warning: Using USCSI interface.\n"); if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { errno = EINVAL; if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Illegal value for busno, target or lun '%d,%d,%d'", busno, tgt, tlun); return (-1); } if (scgp->local == NULL) { scgp->local = malloc(sizeof(struct scg_local)); if (scgp->local == NULL) return (0); scglocal(scgp)->isuscsi = 0; } if (scglocal(scgp)->isuscsi == 0) { for (b=0; b < MAX_SCG; b++) { for (t=0; t < MAX_TGT; t++) { for (l=0; l < MAX_LUN ; l++) scglocal(scgp)->u.scgfiles[b][t][l] = (short)-1; } } scglocal(scgp)->isuscsi = 1; } if (device != NULL && strcmp(device, "USCSI") == 0) goto uscsiscan; if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) goto openbydev;uscsiscan: if (busno >= 0 && tgt >= 0 && tlun >= 0) { if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) return (-1); js_snprintf(devname, sizeof(devname), "/dev/rdsk/c%dt%dd%ds2", busno, tgt, tlun); f = open(devname, O_RDONLY | O_NDELAY); if (f < 0) { js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '%s'", devname); return (0); } scglocal(scgp)->u.scgfiles[busno][tgt][tlun] = f; return 1; } else { for (b=0; b < MAX_SCG; b++) { for (t=0; t < MAX_TGT; t++) { for (l=0; l < MAX_LUN ; l++) { js_snprintf(devname, sizeof(devname), "/dev/rdsk/c%dt%dd%ds2", b, t, l); f = open(devname, O_RDONLY | O_NDELAY); if (f < 0 && errno != ENOENT && errno != ENXIO && errno != ENODEV) { if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '%s'", devname); } if (f < 0 && l == 0) break; if (f >= 0) { nopen ++; if (scglocal(scgp)->u.scgfiles[b][t][l] == -1) scglocal(scgp)->u.scgfiles[b][t][l] = f; else close(f); } } } } }openbydev: if (nopen == 0) { int target; int lun; if (device == NULL || device[0] == '\0') return (0); f = open(device, O_RDONLY | O_NDELAY); if (f < 0) { js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '%s'", device); return (0); } if (busno < 0) busno = 0; /* Use Fake number if not specified */ scgp->scsibus = busno; if (scsi_ugettlun(f, &target, &lun) >= 0) { if (tgt >= 0 && tlun >= 0) { if (tgt != target || tlun != lun) { close(f); return (0); } } tgt = target; tlun = lun; } else { if (tgt < 0 || tlun < 0) { close(f); return (0); } } scgp->target = tgt; scgp->lun = tlun; if (scglocal(scgp)->u.scgfiles[busno][tgt][tlun] == -1) scglocal(scgp)->u.scgfiles[busno][tgt][tlun] = f; return (++nopen); } return (nopen);}LOCAL intscsi_uclose(scgp) SCSI *scgp;{ register int f; register int b; register int t; register int l; if (scgp->local == NULL) return (-1); for (b=0; b < MAX_SCG; b++) { for (t=0; t < MAX_TGT; t++) { for (l=0; l < MAX_LUN ; l++) { f = scglocal(scgp)->u.scgfiles[b][t][l]; if (f >= 0) close(f); scglocal(scgp)->u.scgfiles[b][t][l] = (short)-1; } } } return (0);}LOCAL intscsi_ucinfo(f, cp, debug) int f; struct dk_cinfo *cp; int debug;{ fillbytes(cp, sizeof(*cp), '\0'); if (ioctl(f, DKIOCINFO, cp) < 0) return (-1); if (debug <= 0) return (0); printf("cname: '%s'\n", cp->dki_cname); printf("ctype: 0x%04hX %hd\n", cp->dki_ctype, cp->dki_ctype); printf("cflags: 0x%04hX\n", cp->dki_flags); printf("cnum: %hd\n", cp->dki_cnum);#ifdef __EVER__ printf("addr: %d\n", cp->dki_addr); printf("space: %d\n", cp->dki_space); printf("prio: %d\n", cp->dki_prio); printf("vec: %d\n", cp->dki_vec);#endif printf("dname: '%s'\n", cp->dki_dname); printf("unit: %d\n", cp->dki_unit); printf("slave: %d %04o Tgt: %d Lun: %d\n", cp->dki_slave, cp->dki_slave, TARGET(cp->dki_slave), LUN(cp->dki_slave)); printf("partition: %hd\n", cp->dki_partition); printf("maxtransfer: %d (%d)\n", cp->dki_maxtransfer, cp->dki_maxtransfer * DEV_BSIZE); return (0);}LOCAL intscsi_ugettlun(f, tgtp, lunp) int f; int *tgtp; int *lunp;{ struct dk_cinfo ci; if (scsi_ucinfo(f, &ci, 0) < 0) return (-1); if (tgtp) *tgtp = TARGET(ci.dki_slave); if (lunp) *lunp = LUN(ci.dki_slave); return (0);}LOCAL longscsi_umaxdma(scgp, amt) SCSI *scgp; long amt;{ register int b; register int t; register int l; long maxdma = -1L; int f; struct dk_cinfo ci; if (scgp->local == NULL) return (-1L); for (b=0; b < MAX_SCG; b++) { for (t=0; t < MAX_TGT; t++) { for (l=0; l < MAX_LUN ; l++) { if ((f = scglocal(scgp)->u.scgfiles[b][t][l]) < 0) continue; if (scsi_ucinfo(f, &ci, 0) < 0) continue; if (maxdma < 0) maxdma = (long)(ci.dki_maxtransfer * DEV_BSIZE); if (maxdma > (long)(ci.dki_maxtransfer * DEV_BSIZE)) maxdma = (long)(ci.dki_maxtransfer * DEV_BSIZE); } } } return (maxdma);}LOCAL BOOLscsi_uhavebus(scgp, busno) SCSI *scgp; int busno;{ register int t; register int l; if (scgp->local == NULL || busno < 0 || busno >= MAX_SCG) return (FALSE); for (t=0; t < MAX_TGT; t++) { for (l=0; l < MAX_LUN ; l++) if (scglocal(scgp)->u.scgfiles[busno][t][l] >= 0) return (TRUE); } return (FALSE);}LOCAL intscsi_ufileno(scgp, busno, tgt, tlun) SCSI *scgp; int busno; int tgt; int tlun;{ if (scgp->local == NULL || busno < 0 || busno >= MAX_SCG || tgt < 0 || tgt >= MAX_TGT || tlun < 0 || tlun >= MAX_LUN) return (-1); return ((int)scglocal(scgp)->u.scgfiles[busno][tgt][tlun]);}LOCAL intscsi_uinitiator_id(scgp) SCSI *scgp;{ return (-1);}LOCAL int scsi_uisatapi(scgp) SCSI *scgp;{ char devname[32]; char symlinkname[MAXPATHLEN]; int len; int f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun); struct dk_cinfo ci; if (ioctl(f, DKIOCINFO, &ci) < 0) return (-1); js_snprintf(devname, sizeof(devname), "/dev/rdsk/c%dt%dd%ds2", scgp->scsibus, scgp->target, scgp->lun); symlinkname[0] = '\0'; len = readlink(devname, symlinkname, sizeof(symlinkname)); if (len > 0) symlinkname[len] = '\0'; if (len >= 0 && strstr(symlinkname, "ide") != NULL) return (TRUE); else return (FALSE);}LOCAL intscsi_ureset(scgp) SCSI *scgp;{ int f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun); struct uscsi_cmd req; fillbytes(&req, sizeof(req), '\0'); req.uscsi_flags = USCSI_RESET | USCSI_SILENT; /* reset target */ return (ioctl(f, USCSICMD, &req));}LOCAL intscsi_usend(scgp, f, sp) SCSI *scgp; int f; struct scg_cmd *sp;{ struct uscsi_cmd req; int ret; if (f < 0) { sp->error = SCG_FATAL; return (0); } fillbytes(&req, sizeof(req), '\0'); req.uscsi_flags = USCSI_SILENT | USCSI_RQENABLE; if (sp->flags & SCG_RECV_DATA) { req.uscsi_flags |= USCSI_READ; } else if (sp->size > 0) { req.uscsi_flags |= USCSI_WRITE; } req.uscsi_buflen = sp->size; req.uscsi_bufaddr = sp->addr; req.uscsi_timeout = sp->timeout; req.uscsi_cdblen = sp->cdb_len; req.uscsi_rqbuf = (caddr_t) sp->u_sense.cmd_sense; req.uscsi_rqlen = sizeof (sp->u_sense.cmd_sense); req.uscsi_cdb = (caddr_t) &sp->cdb; errno = 0; ret = ioctl(f, USCSICMD, &req); if (scgp->debug) { printf("ret: %d errno: %d (%s)\n", ret, errno, errmsgstr(errno)); printf("uscsi_flags: 0x%x\n", req.uscsi_flags); printf("uscsi_status: 0x%x\n", req.uscsi_status); printf("uscsi_timeout: %d\n", req.uscsi_timeout); printf("uscsi_bufaddr: 0x%lx\n", (long)req.uscsi_bufaddr); printf("uscsi_buflen: %d\n", req.uscsi_buflen); printf("uscsi_resid: %d\n", req.uscsi_resid); printf("uscsi_rqlen: %d\n", req.uscsi_rqlen); printf("uscsi_rqstatus: 0x%x\n", req.uscsi_rqstatus); printf("uscsi_rqresid: %d\n", req.uscsi_rqresid); printf("uscsi_rqbuf: 0x%lx\n", (long)req.uscsi_rqbuf); } if (ret < 0) { sp->ux_errno = geterrno(); /* * Check if SCSI command cound not be send at all. */ if (sp->ux_errno == ENOTTY && scsi_isatapi(scgp) == TRUE) { if (scgp->debug) printf("ENOTTY atapi: %d\n", scsi_isatapi(scgp)); sp->error = SCG_FATAL; return (0); } if (errno == ENOTTY || errno == ENXIO || errno == EINVAL || errno == EACCES) { return (-1); } } else { sp->ux_errno = 0; } ret = 0; sp->sense_count = req.uscsi_rqlen - req.uscsi_rqresid; sp->resid = req.uscsi_resid; sp->u_scb.cmd_scb[0] = req.uscsi_status; if ((req.uscsi_status & STATUS_MASK) == STATUS_GOOD) { sp->error = SCG_NO_ERROR; return (0); } if (req.uscsi_rqstatus == 0 && ((req.uscsi_status & STATUS_MASK) == STATUS_CHECK)) { sp->error = SCG_RETRYABLE; return (0); } if (req.uscsi_status & (STATUS_TERMINATED | STATUS_RESERVATION_CONFLICT)) { sp->error = SCG_FATAL; } if (req.uscsi_status != 0) { sp->error = SCG_RETRYABLE; } return (ret);}#endif /* USE_USCSI */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -