summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_queue.h
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1998-09-15 06:33:23 +0000
committergibbs <gibbs@FreeBSD.org>1998-09-15 06:33:23 +0000
commit855593c295ac3878b7f73a83edd07f899eccc38d (patch)
tree436fdb7e7e00d8403854b3bc0865866cd885e9dd /sys/cam/cam_queue.h
parentbbc0682d67a7e0c50ade831509abd8c3e119db5c (diff)
downloadFreeBSD-src-855593c295ac3878b7f73a83edd07f899eccc38d.zip
FreeBSD-src-855593c295ac3878b7f73a83edd07f899eccc38d.tar.gz
CAM Transport Layer (XPT).
Submitted by: The CAM Team
Diffstat (limited to 'sys/cam/cam_queue.h')
-rw-r--r--sys/cam/cam_queue.h236
1 files changed, 236 insertions, 0 deletions
diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
new file mode 100644
index 0000000..8123222
--- /dev/null
+++ b/sys/cam/cam_queue.h
@@ -0,0 +1,236 @@
+/*
+ * CAM request queue management definitions.
+ *
+ * Copyright (c) 1997 Justin T. Gibbs.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _CAM_CAM_QUEUE_H
+#define _CAM_CAM_QUEUE_H 1
+
+#ifdef KERNEL
+
+#include <sys/queue.h>
+
+/*
+ * This structure implements a heap based priority queue. The queue
+ * assumes that the objects stored in it begin with a cam_qentry
+ * structure holding the priority information used to sort the objects.
+ * This structure is opaque to clients (outside of the XPT layer) to allow
+ * the implementation to change without affecting them.
+ */
+struct camq {
+ cam_pinfo **queue_array;
+ int array_size;
+ int entries;
+ u_int32_t generation;
+ u_int32_t qfrozen_cnt;
+};
+
+TAILQ_HEAD(ccb_hdr_list, ccb_hdr);
+
+struct cam_ccbq {
+ struct camq queue;
+ int devq_openings;
+ int dev_openings;
+ int dev_active;
+ int held;
+ struct ccb_hdr_list active_ccbs;
+};
+
+struct cam_ed;
+
+struct cam_devq {
+ struct camq alloc_queue;
+ struct camq send_queue;
+ struct cam_ed *active_dev;
+ int alloc_openings;
+ int alloc_active;
+ int send_openings;
+ int send_active;
+};
+
+
+struct cam_devq *cam_devq_alloc(int devices, int openings);
+
+int cam_devq_init(struct cam_devq *devq, int devices,
+ int openings);
+
+void cam_devq_free(struct cam_devq *devq);
+
+u_int32_t cam_devq_resize(struct cam_devq *camq, int openings);
+
+/*
+ * Allocate a cam_ccb_queue structure and initialize it.
+ */
+struct cam_ccbq *cam_ccbq_alloc(int openings);
+
+u_int32_t cam_ccbq_resize(struct cam_ccbq *ccbq, int devices);
+
+int cam_ccbq_init(struct cam_ccbq *ccbq, int openings);
+
+void cam_ccbq_free(struct cam_ccbq *ccbq);
+
+void cam_ccbq_fini(struct cam_ccbq *ccbq);
+
+void cam_ccbq_regen(struct cam_ccbq *ccbq);
+
+/*
+ * Allocate and initialize a cam_queue structure.
+ */
+struct camq *camq_alloc(int size);
+
+/*
+ * Resize a cam queue
+ */
+u_int32_t camq_resize(struct camq *queue, int new_size);
+
+/*
+ * Initialize a camq structure. Return 0 on success, 1 on failure.
+ */
+int camq_init(struct camq *camq, int size);
+
+/*
+ * Free a cam_queue structure. This should only be called if a controller
+ * driver failes somehow during its attach routine or is unloaded and has
+ * obtained a cam_queue structure.
+ */
+void camq_free(struct camq *queue);
+
+/*
+ * Finialize any internal storage or state of a cam_queue.
+ */
+void camq_fini(struct camq *queue);
+
+/*
+ * cam_queue_insert: Given a CAM queue with at least one open spot,
+ * insert the new entry maintaining order.
+ */
+void camq_insert(struct camq *queue, cam_pinfo *new_entry);
+
+/*
+ * camq_remove: Remove and arbitrary entry from the queue maintaining
+ * queue order.
+ */
+cam_pinfo *camq_remove(struct camq *queue, int index);
+
+/*
+ * camq_change_priority: Raise or lower the priority of an entry
+ * maintaining queue order.
+ */
+void camq_change_priority(struct camq *queue, int index,
+ u_int32_t new_priority);
+
+void camq_regen(struct camq *queue);
+
+static __inline int
+cam_ccbq_pending_ccb_count(struct cam_ccbq *ccbq);
+
+static __inline void
+cam_ccbq_take_opening(struct cam_ccbq *ccbq);
+
+static __inline void
+cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb);
+
+static __inline void
+cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb);
+
+static __inline union ccb *
+cam_ccbq_peek_ccb(struct cam_ccbq *ccbq, int index);
+
+static __inline void
+cam_ccbq_send_ccb(struct cam_ccbq *queue, union ccb *send_ccb);
+
+static __inline void
+cam_ccbq_ccb_done(struct cam_ccbq *ccbq, union ccb *done_ccb);
+
+static __inline void
+cam_ccbq_release_opening(struct cam_ccbq *ccbq);
+
+
+static __inline int
+cam_ccbq_pending_ccb_count(struct cam_ccbq *ccbq)
+{
+ return (ccbq->queue.entries);
+}
+
+static __inline void
+cam_ccbq_take_opening(struct cam_ccbq *ccbq)
+{
+ ccbq->devq_openings--;
+ ccbq->held++;
+}
+
+static __inline void
+cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb)
+{
+ ccbq->held--;
+ camq_insert(&ccbq->queue, &new_ccb->ccb_h.pinfo);
+}
+
+static __inline void
+cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb)
+{
+ camq_remove(&ccbq->queue, ccb->ccb_h.pinfo.index);
+}
+
+static __inline union ccb *
+cam_ccbq_peek_ccb(struct cam_ccbq *ccbq, int index)
+{
+ return((union ccb *)ccbq->queue.queue_array[index]);
+}
+
+static __inline void
+cam_ccbq_send_ccb(struct cam_ccbq *ccbq, union ccb *send_ccb)
+{
+
+ TAILQ_INSERT_TAIL(&ccbq->active_ccbs,
+ &(send_ccb->ccb_h),
+ xpt_links.tqe);
+ send_ccb->ccb_h.pinfo.index = CAM_ACTIVE_INDEX;
+ ccbq->dev_active++;
+ ccbq->dev_openings--;
+}
+
+static __inline void
+cam_ccbq_ccb_done(struct cam_ccbq *ccbq, union ccb *done_ccb)
+{
+ TAILQ_REMOVE(&ccbq->active_ccbs, &done_ccb->ccb_h,
+ xpt_links.tqe);
+ ccbq->dev_active--;
+ ccbq->dev_openings++;
+ ccbq->held++;
+}
+
+static __inline void
+cam_ccbq_release_opening(struct cam_ccbq *ccbq)
+{
+ ccbq->held--;
+ ccbq->devq_openings++;
+}
+
+#endif /* KERNEL */
+#endif /* _CAM_CAM_QUEUE_H */
OpenPOWER on IntegriCloud