summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>1999-08-20 03:48:11 +0000
committerken <ken@FreeBSD.org>1999-08-20 03:48:11 +0000
commite6adc2c52ec8788c8eb3ad672e6ced99a9b58607 (patch)
treeeb6d964c55a4f9bf8e661501cc094b71976e6b84 /sys/cam/scsi
parent36d05ff1872b2d6a868dd0054ffb6787caab14ac (diff)
downloadFreeBSD-src-e6adc2c52ec8788c8eb3ad672e6ced99a9b58607.zip
FreeBSD-src-e6adc2c52ec8788c8eb3ad672e6ced99a9b58607.tar.gz
Fix short timeout problems with the pt(4) driver:
- increase the default timeout from 10 seconds to 60 seconds - add a new kernel option, SCSI_PT_DEFAULT_TIMEOUT, that lets users specify the default timeout for the pt driver to use - add two new ioctls, one to get the timeout for a given pt device, the other to set the timeout for a given pt device. The idea is that userland applications using the device can set the timeout to suit their purposes. The ioctls are defined in a new header file, sys/ptio.h PR: 10266 Reviewed by: gibbs, joerg
Diffstat (limited to 'sys/cam/scsi')
-rw-r--r--sys/cam/scsi/scsi_pt.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/sys/cam/scsi/scsi_pt.c b/sys/cam/scsi/scsi_pt.c
index 77dea13..92ed7b9 100644
--- a/sys/cam/scsi/scsi_pt.c
+++ b/sys/cam/scsi/scsi_pt.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: scsi_pt.c,v 1.10 1999/05/31 11:24:07 phk Exp $
+ * $Id: scsi_pt.c,v 1.11 1999/08/17 20:25:47 billf Exp $
*/
#include <sys/param.h>
@@ -37,6 +37,7 @@
#include <sys/devicestat.h>
#include <sys/malloc.h>
#include <sys/conf.h>
+#include <sys/ptio.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -49,6 +50,8 @@
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pt.h>
+#include "opt_pt.h"
+
typedef enum {
PT_STATE_PROBE,
PT_STATE_NORMAL
@@ -79,6 +82,7 @@ struct pt_softc {
pt_state state;
pt_flags flags;
union ccb saved_ccb;
+ int io_timeout;
};
static d_open_t ptopen;
@@ -93,6 +97,7 @@ static periph_dtor_t ptdtor;
static periph_start_t ptstart;
static void ptdone(struct cam_periph *periph,
union ccb *done_ccb);
+static d_ioctl_t ptioctl;
static int pterror(union ccb *ccb, u_int32_t cam_flags,
u_int32_t sense_flags);
@@ -117,7 +122,7 @@ static struct cdevsw pt_cdevsw = {
/* close */ ptclose,
/* read */ physread,
/* write */ physwrite,
- /* ioctl */ noioctl,
+ /* ioctl */ ptioctl,
/* stop */ nostop,
/* reset */ noreset,
/* devtotty */ nodevtotty,
@@ -136,6 +141,10 @@ static struct cdevsw pt_cdevsw = {
static struct extend_array *ptperiphs;
+#ifndef SCSI_PT_DEFAULT_TIMEOUT
+#define SCSI_PT_DEFAULT_TIMEOUT 60
+#endif
+
static int
ptopen(dev_t dev, int flags, int fmt, struct proc *p)
{
@@ -339,6 +348,8 @@ ptctor(struct cam_periph *periph, void *arg)
softc->state = PT_STATE_NORMAL;
bufq_init(&softc->buf_queue);
+ softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000;
+
periph->softc = softc;
cam_extend_set(ptperiphs, periph->unit_number, periph);
@@ -543,7 +554,7 @@ ptstart(struct cam_periph *periph, union ccb *start_ccb)
bp->b_bcount,
bp->b_data,
/*sense_len*/SSD_FULL_SIZE,
- /*timeout*/10000);
+ /*timeout*/softc->io_timeout);
start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO;
@@ -694,6 +705,58 @@ pterror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
&softc->saved_ccb));
}
+static int
+ptioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
+{
+ struct cam_periph *periph;
+ struct pt_softc *softc;
+ int unit;
+ int error;
+
+ unit = minor(dev);
+ periph = cam_extend_get(ptperiphs, unit);
+
+ if (periph == NULL)
+ return(ENXIO);
+
+ softc = (struct pt_softc *)periph->softc;
+
+ if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) {
+ return (error); /* error code from tsleep */
+ }
+
+ switch(cmd) {
+ case PTIOCGETTIMEOUT:
+ if (softc->io_timeout >= 1000)
+ *(int *)addr = softc->io_timeout / 1000;
+ else
+ *(int *)addr = 0;
+ break;
+ case PTIOCSETTIMEOUT:
+ {
+ int s;
+
+ if (*(int *)addr < 1) {
+ error = EINVAL;
+ break;
+ }
+
+ s = splsoftcam();
+ softc->io_timeout = *(int *)addr * 1000;
+ splx(s);
+
+ break;
+ }
+ default:
+ error = cam_periph_ioctl(periph, cmd, addr, pterror);
+ break;
+ }
+
+ cam_periph_unlock(periph);
+
+ return(error);
+}
+
void
scsi_send_receive(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
OpenPOWER on IntegriCloud