summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1999-04-07 22:57:48 +0000
committergibbs <gibbs@FreeBSD.org>1999-04-07 22:57:48 +0000
commit71072fc11358b4c222da690ee5866cc00f1a8fe3 (patch)
tree4a033fb4ddaf6f21087caaa4afb9d6905a2eecb2 /sys/cam
parent9e60b40925fe4dbc882d66c232811d1366a442c1 (diff)
downloadFreeBSD-src-71072fc11358b4c222da690ee5866cc00f1a8fe3.zip
FreeBSD-src-71072fc11358b4c222da690ee5866cc00f1a8fe3.tar.gz
Remove camq_regen(). We already perform modular comparisons
for generation counts, so no further steps to deal with generation count wrap are required. Fix an off by one problem in the camq heap code.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/cam.h13
-rw-r--r--sys/cam/cam_queue.c50
-rw-r--r--sys/cam/cam_queue.h6
-rw-r--r--sys/cam/cam_xpt.c42
4 files changed, 39 insertions, 72 deletions
diff --git a/sys/cam/cam.h b/sys/cam/cam.h
index 21aea02..c182fd6 100644
--- a/sys/cam/cam.h
+++ b/sys/cam/cam.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cam.h,v 1.1 1998/09/15 06:33:23 gibbs Exp $
*/
#ifndef _CAM_CAM_H
@@ -74,6 +74,17 @@ typedef struct {
#define CAM_DONEQ_INDEX -3
} cam_pinfo;
+/*
+ * Macro to compare two generation numbers. It is used like this:
+ *
+ * if (GENERATIONCMP(a, >=, b))
+ * ...;
+ *
+ * GERERATIONCMP uses modular arithmetic to guard against wraps
+ * wraps in the generation number.
+ */
+#define GENERATIONCMP(x, op, y) ((int32_t)((x) - (y)) op 0)
+
/* CAM flags */
typedef enum {
CAM_FLAG_NONE = 0x00,
diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c
index 809955e..edebfd5 100644
--- a/sys/cam/cam_queue.c
+++ b/sys/cam/cam_queue.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cam_queue.c,v 1.1 1998/09/15 06:33:23 gibbs Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -126,27 +126,6 @@ camq_resize(struct camq *queue, int new_size)
}
/*
- * camq_regen: Given an array of cam_pinfo* elements with the
- * Heap(0, num_elements) property, perform the second half of
- * a heap sort, and assign new generation numbers to all entries.
- * It is assumed that the starting generation number plus the
- * number of entries in the queue is smaller than the wrap point
- * of the generation number.
- */
-void
-camq_regen(struct camq *queue)
-{
- int index;
-
- for (index = 0; index < queue->entries; index++) {
-
- heap_down(queue->queue_array, index, queue->entries);
- queue->queue_array[index]->generation = queue->generation++;
- }
- /* A sorted array is still a heap, so we are done */
-}
-
-/*
* camq_insert: Given an array of cam_pinfo* elememnts with
* the Heap(0, num_elements) property and array_size - num_elements >= 1,
* output Heap(0, num_elements+1) including new_entry in the array.
@@ -336,23 +315,6 @@ cam_ccbq_init(struct cam_ccbq *ccbq, int openings)
return (0);
}
-void
-cam_ccbq_regen(struct cam_ccbq *ccbq)
-{
- struct ccb_hdr *ccbh;
-
- /* First get all of the guys down at a device */
- ccbh = ccbq->active_ccbs.tqh_first;
-
- while (ccbh != NULL) {
- ccbh->pinfo.generation = ccbq->queue.generation++;
- ccbh = ccbh->xpt_links.tqe.tqe_next;
- }
-
- /* Now get everyone in our CAM queue */
- camq_regen(&ccbq->queue);
-}
-
/*
* Heap routines for manipulating CAM queues.
*/
@@ -403,7 +365,7 @@ heap_up(cam_pinfo **queue_array, int new_index)
while (child != 0) {
- parent = child >> 1;
+ parent = (child - 1) >> 1;
if (queue_cmp(queue_array, parent, child) <= 0)
break;
swap(queue_array, parent, child);
@@ -413,8 +375,8 @@ heap_up(cam_pinfo **queue_array, int new_index)
/*
* heap_down: Given an array of cam_pinfo* elements with the
- * Heap(1, num_entries - 1) property with index 0 containing an unsorted
- * entry, output Heap(0, num_entries - 1).
+ * Heap(index + 1, num_entries - 1) property with index containing
+ * an unsorted entry, output Heap(0, num_entries - 1).
*/
static void
heap_down(cam_pinfo **queue_array, int index, int num_entries)
@@ -423,8 +385,8 @@ heap_down(cam_pinfo **queue_array, int index, int num_entries)
int parent;
parent = index;
- child = parent == 0 ? 1 : parent << 1;
- for (; child < num_entries; child = parent << 1) {
+ child = (parent << 1) + 1;
+ for (; child < num_entries; child = (parent << 1) + 1) {
if (child + 1 < num_entries) {
/* child+1 is the right child of parent */
diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
index 7e3d0df..c9135b7 100644
--- a/sys/cam/cam_queue.h
+++ b/sys/cam/cam_queue.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cam_queue.h,v 1.1 1998/09/15 06:33:23 gibbs Exp $
+ * $Id: cam_queue.h,v 1.2 1998/12/15 08:12:03 gibbs Exp $
*/
#ifndef _CAM_CAM_QUEUE_H
@@ -98,8 +98,6 @@ 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.
*/
@@ -146,8 +144,6 @@ cam_pinfo *camq_remove(struct camq *queue, int index);
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);
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index dcdc663..e44d6b2 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cam_xpt.c,v 1.48 1999/03/11 10:48:02 jkh Exp $
+ * $Id: cam_xpt.c,v 1.49 1999/03/14 05:15:38 ken Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -3292,12 +3292,8 @@ xpt_schedule(struct cam_periph *perph, u_int32_t new_priority)
/* New entry on the queue */
CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
(" added periph to queue\n"));
- if (device->drvq.generation++ == 0) {
- /* Generation wrap, regen all entries */
- camq_regen(&device->drvq);
- }
perph->pinfo.priority = new_priority;
- perph->pinfo.generation = device->drvq.generation;
+ perph->pinfo.generation = ++device->drvq.generation;
camq_insert(&device->drvq, &perph->pinfo);
runq = xpt_schedule_dev_allocq(perph->path->bus, device);
}
@@ -3350,11 +3346,7 @@ xpt_schedule_dev(struct camq *queue, cam_pinfo *pinfo,
CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
("Inserting onto queue\n"));
- if (queue->generation++ == 0) {
- /* Generation wrap, regen all entries */
- camq_regen(queue);
- }
- pinfo->generation = queue->generation;
+ pinfo->generation = ++queue->generation;
camq_insert(queue, pinfo);
retval = 1;
}
@@ -3611,12 +3603,8 @@ xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
else
ccb_h->target_id = CAM_TARGET_WILDCARD;
if (path->device) {
- if (path->device->ccbq.queue.generation++ == 0) {
- /* Generation wrap, regen all entries */
- cam_ccbq_regen(&path->device->ccbq);
- }
ccb_h->target_lun = path->device->lun_id;
- ccb_h->pinfo.generation = path->device->ccbq.queue.generation;
+ ccb_h->pinfo.generation = ++path->device->ccbq.queue.generation;
} else {
ccb_h->target_lun = CAM_TARGET_WILDCARD;
}
@@ -5588,7 +5576,8 @@ xpt_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
}
qfrozen = FALSE;
- if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
+ if ((cts->valid & CCB_TRANS_TQ_VALID) != 0
+ && (async_update == FALSE)) {
int device_tagenb;
/*
@@ -5629,15 +5618,24 @@ xpt_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
device->tag_delay_count = 0;
}
- } else if ((cts->flags & (CCB_TRANS_SYNC_RATE_VALID|
- CCB_TRANS_SYNC_OFFSET_VALID|
- CCB_TRANS_BUS_WIDTH_VALID)) != 0) {
- xpt_toggle_tags(cts->ccb_h.path);
}
}
- if (async_update == FALSE)
+ if (async_update == FALSE) {
+ /*
+ * If we are currently performing tagged transactions to
+ * this device and want to change its negotiation parameters,
+ * go non-tagged for a bit to give the controller a chance to
+ * negotiate unhampered by tag messages.
+ */
+ if ((device->inq_flags & SID_CmdQue) != 0
+ && (cts->flags & (CCB_TRANS_SYNC_RATE_VALID|
+ CCB_TRANS_SYNC_OFFSET_VALID|
+ CCB_TRANS_BUS_WIDTH_VALID)) != 0)
+ xpt_toggle_tags(cts->ccb_h.path);
+
(*(sim->sim_action))(sim, (union ccb *)cts);
+ }
if (qfrozen) {
struct ccb_relsim crs;
OpenPOWER on IntegriCloud