diff options
author | scottl <scottl@FreeBSD.org> | 2007-04-10 20:03:42 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-04-10 20:03:42 +0000 |
commit | 2cece7cde24859369fba558ea30f783e68dd772a (patch) | |
tree | 8ac5d9ee2b2257d08a56379225203460e120eea8 /sys/cam | |
parent | 56a3d8cfd377ad7cce05adf21c9f9770dc74db12 (diff) | |
download | FreeBSD-src-2cece7cde24859369fba558ea30f783e68dd772a.zip FreeBSD-src-2cece7cde24859369fba558ea30f783e68dd772a.tar.gz |
A fix for the SG_GET_TIMEOUT function slipped into a previous commit by
accident. Remove the text describing the problem as it is no longer
relevant. Also give real implementations for the GET and SET ioctls.
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/scsi/scsi_sg.c | 25 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_sg.h | 5 |
2 files changed, 22 insertions, 8 deletions
diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c index b51d0d9..38942eb 100644 --- a/sys/cam/scsi/scsi_sg.c +++ b/sys/cam/scsi/scsi_sg.c @@ -100,11 +100,13 @@ struct sg_rdwr { struct sg_softc { sg_state state; sg_flags flags; - uint8_t pd_type; struct devstat *device_stats; TAILQ_HEAD(, sg_rdwr) rdwr_done; struct cdev *dev; struct cdev *devalias; + int sg_timeout; + int sg_user_timeout; + uint8_t pd_type; union ccb saved_ccb; }; @@ -297,6 +299,8 @@ sgregister(struct cam_periph *periph, void *arg) softc->state = SG_STATE_NORMAL; softc->pd_type = SID_TYPE(&cgd->inq_data); + softc->sg_timeout = SG_DEFAULT_TIMEOUT / SG_DEFAULT_HZ * hz; + softc->sg_user_timeout = SG_DEFAULT_TIMEOUT; TAILQ_INIT(&softc->rdwr_done); periph->softc = softc; @@ -495,17 +499,22 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) error = copyout(&sg_version, arg, sizeof(sg_version)); break; case SG_SET_TIMEOUT: - case LINUX_SG_SET_TIMEOUT: + case LINUX_SG_SET_TIMEOUT: { + u_int user_timeout; + + error = copyin(arg, &user_timeout, sizeof(u_int)); + if (error == 0) { + softc->sg_user_timeout = user_timeout; + softc->sg_timeout = user_timeout / SG_DEFAULT_HZ * hz; + } break; + } case SG_GET_TIMEOUT: case LINUX_SG_GET_TIMEOUT: /* - * XXX This ioctl is highly brain damaged because it requires - * that the value be returned in the syscall return value. - * The linuxolator seems to have a hard time with this, - * so just return 0 and hope that apps can cope. + * The value is returned directly to the syscall. */ - td->td_retval[0] = 60*hz; + td->td_retval[0] = softc->sg_user_timeout; error = 0; break; case SG_IO: @@ -751,7 +760,7 @@ sgwrite(struct cdev *dev, struct uio *uio, int ioflag) buf_len, SG_MAX_SENSE, cdb_len, - 60*hz); + sc->sg_timeout); /* * Send off the command and hope that it works. This path does not diff --git a/sys/cam/scsi/scsi_sg.h b/sys/cam/scsi/scsi_sg.h index a9f7d03..60dbbfe 100644 --- a/sys/cam/scsi/scsi_sg.h +++ b/sys/cam/scsi/scsi_sg.h @@ -136,4 +136,9 @@ struct scsi_idlun { #define DRIVER_MASK 0x0f #define SUGGEST_MASK 0xf0 +/* Other definitions */ +/* HZ isn't always available, so simulate it */ +#define SG_DEFAULT_HZ 1000 +#define SG_DEFAULT_TIMEOUT (60*SG_DEFAULT_HZ) + #endif /* !_SCSI_SG_H */ |