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.
This commit is contained in:
Justin T. Gibbs 1999-04-07 22:57:48 +00:00
parent 29089b519d
commit 8bad620d54
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=45441
4 changed files with 39 additions and 72 deletions

View File

@ -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,

View File

@ -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>
@ -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 */

View File

@ -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);

View File

@ -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;