summaryrefslogtreecommitdiff
path: root/sys/scsi/scsiconf.h
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2010-04-06 00:58:01 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2010-04-06 00:58:01 +0000
commit84cd084901fdee8a8e3fae3a885b533c9a29b1d5 (patch)
treeb95204b31eb1a1af9f736150e4cd9386b87b48e0 /sys/scsi/scsiconf.h
parent79fb0239fb794c3a4a1eb6f7145f92d0a923b81c (diff)
implement a new mechanism for allocating resources on the bus.
instead of optimistically trying to use a resource by executing an xs and then failing when there's no room for it, this puts things that want to use the hardware on a runqueue. as resources become available on the bus then consumers on the runqueue are popped off and guaranteed access to the resource. the resources are generally "ccbs" in adapter drivers, so this abstracts a way for the midlayer to get access to them into something called iopools. it also provides a callback api for consumers of resources to use: the scsi_ioh api for things that want direct access to the ccbs, and the scsi_xsh api for things that want to issue a scsi_xfer on the bus. these apis have been modelled on the timeout api. scsi_xs_get and therefore scsi_scs_cmd have been cut over to using these apis internally, so if they are allowed to sleep then can wait on the runqueue for a resource to become available and therefore guarantee that when executed on an adapter providing an iopool that they will succeed. ok krw@ beck@ marco@ tested by many including krw@ beck@ mk@ okan@ todd@
Diffstat (limited to 'sys/scsi/scsiconf.h')
-rw-r--r--sys/scsi/scsiconf.h85
1 files changed, 84 insertions, 1 deletions
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index 7a9a9b05f1d..72257b98703 100644
--- a/sys/scsi/scsiconf.h
+++ b/sys/scsi/scsiconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.h,v 1.120 2010/03/23 01:57:20 krw Exp $ */
+/* $OpenBSD: scsiconf.h,v 1.121 2010/04/06 00:58:00 dlg Exp $ */
/* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
/*
@@ -327,6 +327,52 @@ struct scsi_device {
};
/*
+ *
+ */
+
+struct scsi_runq_entry {
+ TAILQ_ENTRY(scsi_runq_entry) e;
+};
+TAILQ_HEAD(scsi_runq, scsi_runq_entry);
+
+struct scsi_iopool;
+
+struct scsi_iohandler {
+ struct scsi_runq_entry entry; /* must be first */
+ u_int onq;
+
+ struct scsi_iopool *pool;
+ void (*handler)(void *, void *);
+ void *cookie;
+};
+
+struct scsi_iopool {
+ /* access to the IOs */
+ void *iocookie;
+ void *(*io_get)(void *);
+ void (*io_put)(void *, void *);
+
+ /* the runqueue */
+ struct scsi_runq queue;
+ /* runqueue semaphore */
+ u_int running;
+ /* protection for the runqueue and its semaphore */
+ struct mutex mtx;
+};
+
+/*
+ *
+ */
+
+struct scsi_xshandler {
+ struct scsi_iohandler ioh; /* must be first */
+ u_int onq;
+
+ struct scsi_link *link;
+ void (*handler)(struct scsi_xfer *);
+};
+
+/*
* This structure describes the connection between an adapter driver and
* a device driver, and is used by each to call services provided by
* the other, and to allow generic scsi glue code to call these services
@@ -356,6 +402,7 @@ struct scsi_link {
#define SDEV_2NDBUS 0x0400 /* device is a 'second' bus device */
#define SDEV_UMASS 0x0800 /* device is UMASS SCSI */
#define SDEV_VIRTUAL 0x1000 /* device is virtualised on the hba */
+#define SDEV_OWN_IOPL 0x2000 /* scsibus */
u_int16_t quirks; /* per-device oddities */
#define SDEV_AUTOSAVE 0x0001 /* do implicit SAVEDATAPOINTER on disconnect */
#define SDEV_NOSYNC 0x0002 /* does not grok SDTR */
@@ -375,6 +422,11 @@ struct scsi_link {
struct scsi_inquiry_data inqdata; /* copy of INQUIRY data from probe */
struct devid *id;
struct mutex mtx;
+
+ struct scsi_runq queue;
+ u_int running;
+
+ struct scsi_iopool *pool;
};
int scsiprint(void *, const char *);
@@ -452,6 +504,8 @@ struct scsi_xfer {
struct timeout stimeout;
void *cookie;
void (*done)(struct scsi_xfer *);
+
+ void *io; /* adapter io resource */
};
/*
@@ -551,6 +605,7 @@ int scsi_interpret_sense(struct scsi_xfer *);
void scsi_buf_enqueue(struct buf *, struct buf *, struct mutex *);
struct buf *scsi_buf_dequeue(struct buf *, struct mutex *);
void scsi_buf_requeue(struct buf *, struct buf *, struct mutex *);
+int scsi_buf_canqueue(struct buf *, struct mutex *);
void scsi_buf_killqueue(struct buf *, struct mutex *);
void scsi_xs_show(struct scsi_xfer *);
@@ -581,6 +636,34 @@ int scsi_xs_sync(struct scsi_xfer *);
void scsi_xs_put(struct scsi_xfer *);
/*
+ * iopool stuff
+ */
+void scsi_iopool_init(struct scsi_iopool *, void *,
+ void *(*)(void *), void (*)(void *, void *));
+
+void * scsi_io_get(struct scsi_iopool *, int);
+void scsi_io_put(struct scsi_iopool *, void *);
+
+/*
+ * default io allocator.
+ */
+void * scsi_default_get(void *);
+void scsi_default_put(void *, void *);
+
+/*
+ * io handler interface
+ */
+void scsi_ioh_set(struct scsi_iohandler *, struct scsi_iopool *,
+ void (*)(void *, void *), void *);
+void scsi_ioh_add(struct scsi_iohandler *);
+void scsi_ioh_del(struct scsi_iohandler *);
+
+void scsi_xsh_set(struct scsi_xshandler *, struct scsi_link *,
+ void (*)(struct scsi_xfer *));
+void scsi_xsh_add(struct scsi_xshandler *);
+void scsi_xsh_del(struct scsi_xshandler *);
+
+/*
* Entrypoints for multipathing
*/
int mpath_path_attach(struct scsi_link *);