From 8bad620d540097ff831bebc109b57c864feb053f Mon Sep 17 00:00:00 2001 From: "Justin T. Gibbs" Date: Wed, 7 Apr 1999 22:57:48 +0000 Subject: [PATCH] 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. --- sys/cam/cam.h | 13 +++++++++++- sys/cam/cam_queue.c | 50 ++++++--------------------------------------- sys/cam/cam_queue.h | 6 +----- sys/cam/cam_xpt.c | 42 ++++++++++++++++++------------------- 4 files changed, 39 insertions(+), 72 deletions(-) diff --git a/sys/cam/cam.h b/sys/cam/cam.h index 21aea025772..c182fd62828 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 809955e28dd..edebfd57fe2 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 #include @@ -125,27 +125,6 @@ camq_resize(struct camq *queue, int new_size) return (CAM_REQ_CMP); } -/* - * 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, @@ -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 7e3d0df2ce0..c9135b70822 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 dcdc663424f..e44d6b26465 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 #include @@ -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;