#ifndef _CAM_CAM_QUEUE_H
#define _CAM_CAM_QUEUE_H 1
#ifdef _KERNEL
#include <sys/queue.h>
struct camq {
cam_pinfo **queue_array;
int array_size;
int entries;
u_int32_t generation;
u_int32_t qfrozen_cnt;
};
TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr);
LIST_HEAD(ccb_hdr_list, ccb_hdr);
SLIST_HEAD(ccb_hdr_slist, ccb_hdr);
struct cam_ccbq {
struct camq queue;
int devq_openings;
int dev_openings;
int dev_active;
int held;
struct ccb_hdr_tailq 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;
int refcount;
int max_openings;
};
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_reference(struct cam_devq *devq);
void cam_devq_release(struct cam_devq *devq);
u_int32_t cam_devq_resize(struct cam_devq *camq, int openings);
void cam_devq_set_openings(struct cam_devq *devq, int openings);
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);
struct camq *camq_alloc(int size);
u_int32_t camq_resize(struct camq *queue, int new_size);
int camq_init(struct camq *camq, int size);
void camq_free(struct camq *queue);
void camq_fini(struct camq *queue);
void camq_insert(struct camq *queue, cam_pinfo *new_entry);
cam_pinfo *camq_remove(struct camq *queue, int index);
#define CAMQ_HEAD 1
#define CAMQ_GET_HEAD(camq) ((camq)->queue_array[CAMQ_HEAD])
void camq_change_priority(struct camq *queue, int index,
u_int32_t new_priority);
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
#endif