diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2018-02-22 07:00:28 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2018-02-22 07:00:28 +0000 |
commit | 252086533f8af0736c2a4987cd70a44366837ec1 (patch) | |
tree | 1f9245e247673fdb6ebea13b9aa559e1f869d78c /lib/sg_pt_win32.c | |
parent | 39ea1b548f21c006c311ace897b221b100bfa88d (diff) | |
download | sg3_utils-252086533f8af0736c2a4987cd70a44366837ec1.tar.gz |
sg_lib: add sg_if_can2stdout(); use uint8_t instead of unsigned char; Windows pass-through work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@754 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib/sg_pt_win32.c')
-rw-r--r-- | lib/sg_pt_win32.c | 143 |
1 files changed, 110 insertions, 33 deletions
diff --git a/lib/sg_pt_win32.c b/lib/sg_pt_win32.c index e9bcb094..0357c7ef 100644 --- a/lib/sg_pt_win32.c +++ b/lib/sg_pt_win32.c @@ -125,11 +125,13 @@ struct sg_pt_handle { int bus; /* a.k.a. PathId in MS docs */ int target; int lun; - int scsi_pid; /* -1 if not known */ + int scsi_pdt; /* Peripheral Device Type, -1 if not known */ + // uint32_t nvme_nsid; /* how do we find this given file handle ?? */ int verbose; /* tunnel verbose through to scsi_pt_close_device */ char dname[20]; }; +/* Start zeroed but need to zeroed before use because could be re-use */ static struct sg_pt_handle handle_arr[MAX_OPEN_SIMULT]; struct sg_pt_win32_scsi { @@ -159,7 +161,7 @@ struct sg_pt_win32_scsi { uint32_t dxfer_len; uint32_t mdxfer_len; uint8_t * dxferp; - uint8_t * mdxferp; /* NVMe has metadata buffer */ + uint8_t * mdxferp; /* NVMe has metadata buffer */ uint8_t * sensep; uint8_t * nvme_id_ctlp; uint8_t * free_nvme_id_ctlp; @@ -190,8 +192,8 @@ static int pr2ws(const char * fmt, ...) static int pr2ws(const char * fmt, ...); #endif -static int do_nvme_pt(struct sg_pt_win32_scsi * psp, - struct sg_pt_handle * shp, int time_secs, int vb); +static int nvme_pt(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, + int time_secs, int vb); static int @@ -388,8 +390,11 @@ scsi_pt_open_flags(const char * device_name, int flags, int vb) if (vb) pr2ws("too many open handles (%d)\n", MAX_OPEN_SIMULT); return -EMFILE; - } else + } else { + /* clear any previous contents */ + memset(handle_arr + k, 0, sizeof(struct sg_pt_handle)); handle_arr[k].in_use = true; + } /* unlock */ index = k; shp = handle_arr + index; @@ -438,7 +443,7 @@ scsi_pt_open_flags(const char * device_name, int flags, int vb) shp->bus = bus; shp->target = target; shp->lun = lun; - shp->scsi_pid = -1; + shp->scsi_pdt = -1; shp->verbose = vb; memset(shp->adapter, 0, sizeof(shp->adapter)); strncpy(shp->adapter, "\\\\.\\", 4); @@ -550,15 +555,15 @@ get_scsi_pdt(struct sg_pt_handle *shp, int vb) if ((shp->bus == pid->PathId) && (shp->target == pid->TargetId) && (shp->lun == pid->Lun)) { /* got match */ - shp->scsi_pid = pid->InquiryData[0] & 0x3f; + shp->scsi_pdt = pid->InquiryData[0] & 0x3f; shp->not_claimed = ! pid->DeviceClaimed; shp->checked_handle = true; shp->bus_type_failed = false; if (vb > 3) - pr2ws("%s: found, scsi_pid=%d, claimed=%d, " - "target=%d, lun=%d\n", __func__, shp->scsi_pid, + pr2ws("%s: found, scsi_pdt=%d, claimed=%d, " + "target=%d, lun=%d\n", __func__, shp->scsi_pdt, pid->DeviceClaimed, shp->target, shp->lun); - ret = shp->scsi_pid; + ret = shp->scsi_pdt; goto fini; } off = pid->NextInquiryDataOffset; @@ -694,8 +699,11 @@ construct_scsi_pt_obj_with_fd(int dev_fd, int vb) psp = (struct sg_pt_win32_scsi *)calloc(sizeof(struct sg_pt_win32_scsi), 1); if (psp) { - if (shp && shp->is_nvme) { - psp->is_nvme = true; + psp->dev_fd = (dev_fd < 0) ? -1 : dev_fd; + if (shp) + psp->is_nvme = shp->is_nvme; + if (psp->is_nvme) { + ; /* should be 'psp->nvme_nsid = shp->nvme_nsid' */ } else if (spt_direct) { psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN; @@ -709,9 +717,8 @@ construct_scsi_pt_obj_with_fd(int dev_fd, int vb) offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf); psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT; } - psp->dev_fd = (dev_fd < 0) ? -1 : dev_fd; vp = (struct sg_pt_base *)malloc(sizeof(struct sg_pt_win32_scsi *)); - /* yes, allocating the size of a pointer (8 bytes) */ + /* yes, allocating the size of a pointer (4 or 8 bytes) */ if (vp) vp->implp = psp; else @@ -741,6 +748,76 @@ destruct_scsi_pt_obj(struct sg_pt_base * vp) } } +/* Forget any previous dev_han and install the one given. May attempt to + * find file type (e.g. if pass-though) from OS so there could be an error. + * Returns 0 for success or the same value as get_scsi_pt_os_err() + * will return. dev_han should be >= 0 for a valid file handle or -1 . */ +int +set_pt_file_handle(struct sg_pt_base * vp, int dev_han, int vb) +{ + int res; + struct sg_pt_win32_scsi * psp; + + if (NULL == vp) { + if (vb) + pr2ws(">>>> %s: pointer to object is NULL\n", __func__); + return EINVAL; + } + if ((psp = vp->implp)) { + struct sg_pt_handle * shp; + + if (dev_han < 0) { + psp->dev_fd = -1; + psp->is_nvme = false; + psp->nvme_nsid = 0; + return 0; + } + shp = get_open_pt_handle(psp, dev_han, vb > 1); + if (NULL == shp) { + if (vb) + pr2ws("%s: dev_han (%d) is invalid\n", __func__, dev_han); + psp->os_err = EINVAL; + return psp->os_err; + } + psp->os_err = 0; + psp->transport_err = 0; + psp->in_err = 0; + psp->scsi_status = 0; + psp->dev_fd = dev_han; + if (! (shp->bus_type_failed || shp->checked_handle)) { + res = get_bus_type(shp, shp->dname, NULL, vb); + if (res < 0) { + res = get_scsi_pdt(shp, vb); + if (res >= 0) /* clears shp->bus_type_failed on success */ + psp->os_err = 0; + } + if ((res < 0) && (vb > 2)) + pr2ws("%s: get_bus_type() errno=%d\n", __func__, -res); + } + if (shp->bus_type_failed) + psp->os_err = EIO; + if (psp->os_err) + return psp->os_err; + psp->is_nvme = shp->is_nvme; + psp->nvme_nsid = 0; /* should be 'psp->nvme_nsid = shp->nvme_nsid' */ + } + return 0; +} + +/* Valid file handles (which is the return value) are >= 0 . Returns -1 + * if there is no valid file handle. */ +int +get_pt_file_handle(const struct sg_pt_base * vp) +{ + const struct sg_pt_win32_scsi * psp; + + if (vp) { + psp = vp->implp; + return psp ? psp->dev_fd : -1; + } + return -1; +} + /* Keep state information such as dev_fd and nvme_nsid */ void clear_scsi_pt_obj(struct sg_pt_base * vp) @@ -775,7 +852,7 @@ clear_scsi_pt_obj(struct sg_pt_base * vp) } void -set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, +set_scsi_pt_cdb(struct sg_pt_base * vp, const uint8_t * cdb, int cdb_len) { bool scsi_cdb = sg_is_scsi_cdb(cdb, cdb_len); @@ -809,7 +886,7 @@ set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, } void -set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, +set_scsi_pt_sense(struct sg_pt_base * vp, uint8_t * sense, int sense_len) { struct sg_pt_win32_scsi * psp = vp->implp; @@ -823,7 +900,7 @@ set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, /* from device */ void -set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, +set_scsi_pt_data_in(struct sg_pt_base * vp, uint8_t * dxferp, int dxfer_len) { struct sg_pt_win32_scsi * psp = vp->implp; @@ -843,7 +920,7 @@ set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, /* to device */ void -set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, +set_scsi_pt_data_out(struct sg_pt_base * vp, const uint8_t * dxferp, int dxfer_len) { struct sg_pt_win32_scsi * psp = vp->implp; @@ -851,7 +928,7 @@ set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, if (psp->dxferp) ++psp->in_err; if (dxfer_len > 0) { - psp->dxferp = (unsigned char *)dxferp; + psp->dxferp = (uint8_t *)dxferp; psp->dxfer_len = (uint32_t)dxfer_len; if (spt_direct) psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_OUT; @@ -861,7 +938,7 @@ set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, } void -set_pt_metadata_xfer(struct sg_pt_base * vp, unsigned char * mdxferp, +set_pt_metadata_xfer(struct sg_pt_base * vp, uint8_t * mdxferp, uint32_t mdxfer_len, bool out_true) { struct sg_pt_win32_scsi * psp = vp->implp; @@ -920,8 +997,8 @@ set_scsi_pt_flags(struct sg_pt_base * objp, int flags) * using direct interface. Clears os_err field prior to active call (whose * result may set it again). */ static int -do_scsi_pt_direct(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, - int time_secs, int vb) +scsi_pt_direct(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, + int time_secs, int vb) { BOOL status; DWORD returned; @@ -996,8 +1073,8 @@ do_scsi_pt_direct(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, * indirect interface. Clears os_err field prior to active call (whose * result may set it again). */ static int -do_scsi_pt_indirect(struct sg_pt_base * vp, struct sg_pt_handle * shp, - int time_secs, int vb) +scsi_pt_indirect(struct sg_pt_base * vp, struct sg_pt_handle * shp, + int time_secs, int vb) { BOOL status; DWORD returned; @@ -1019,7 +1096,7 @@ do_scsi_pt_indirect(struct sg_pt_base * vp, struct sg_pt_handle * shp, epsp = (struct sg_pt_win32_scsi *) calloc(sizeof(struct sg_pt_win32_scsi) + extra, 1); if (NULL == epsp) { - pr2ws("do_scsi_pt: failed to enlarge data buffer to %d bytes\n", + pr2ws("%s: failed to enlarge data buffer to %d bytes\n", __func__, psp->dxfer_len); psp->os_err = ENOMEM; return -psp->os_err; @@ -1149,11 +1226,11 @@ do_scsi_pt(struct sg_pt_base * vp, int dev_fd, int time_secs, int vb) psp->is_nvme = shp->is_nvme; if (psp->is_nvme) - return do_nvme_pt(psp, shp, time_secs, vb); + return nvme_pt(psp, shp, time_secs, vb); else if (spt_direct) - return do_scsi_pt_direct(psp, shp, time_secs, vb); + return scsi_pt_direct(psp, shp, time_secs, vb); else - return do_scsi_pt_indirect(vp, shp, time_secs, vb); + return scsi_pt_indirect(vp, shp, time_secs, vb); } int @@ -1215,7 +1292,7 @@ get_scsi_pt_sense_len(const struct sg_pt_base * vp) int get_scsi_pt_duration_ms(const struct sg_pt_base * vp __attribute__ ((unused))) { - // const struct sg_pt_freebsd_scsi * psp = vp->implp; + // const struct sg_pt_win32_scsi * psp = vp->implp; return -1; } @@ -2744,8 +2821,8 @@ sntl_rep_tmfs(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, * When time_secs is 0 the Linux NVMe Admin command default of 60 seconds * is used. */ static int -do_nvme_pt(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, - int time_secs, int vb) +nvme_pt(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, + int time_secs, int vb) { bool scsi_cdb = false; uint32_t cmd_len = 0; @@ -2832,8 +2909,8 @@ do_nvme_pt(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, #else /* (HAVE_NVME && (! IGNORE_NVME)) */ static int -do_nvme_pt(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, - int time_secs, int vb) +nvme_pt(struct sg_pt_win32_scsi * psp, struct sg_pt_handle * shp, + int time_secs, int vb) { if (vb) pr2ws("%s: not supported [time_secs=%d]\n", __func__, time_secs); |