We never allocate >253 scb's, and thus tag collisions should not be possible if they are correctly initialized. This diff just rips out the existing collision code. I haven't yet determined if we need to initialize tags differently.
It is a prerequisite for iopoolification and testing on any ahd hardware would be appreciated. .... Ken Index: aic79xx.c =================================================================== RCS file: /cvs/src/sys/dev/ic/aic79xx.c,v retrieving revision 1.47 diff -u -p -r1.47 aic79xx.c --- aic79xx.c 22 Sep 2010 00:35:19 -0000 1.47 +++ aic79xx.c 5 Apr 2011 12:19:19 -0000 @@ -216,10 +216,6 @@ struct scb * ahd_find_scb_by_tag(struct void ahd_fini_scbdata(struct ahd_softc *ahd); void ahd_setup_iocell_workaround(struct ahd_softc *ahd); void ahd_iocell_first_selection(struct ahd_softc *ahd); -void ahd_add_col_list(struct ahd_softc *ahd, - struct scb *scb, u_int col_idx); -void ahd_rem_col_list(struct ahd_softc *ahd, - struct scb *scb); void ahd_chip_init(struct ahd_softc *ahd); void ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb, @@ -5804,84 +5800,19 @@ ahd_iocell_first_selection(struct ahd_so ahd->flags |= AHD_HAD_FIRST_SEL; } -/*************************** SCB Management ***********************************/ -void -ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx) -{ - struct scb_list *free_list; - struct scb_tailq *free_tailq; - struct scb *first_scb; - - scb->flags |= SCB_ON_COL_LIST; - AHD_SET_SCB_COL_IDX(scb, col_idx); - free_list = &ahd->scb_data.free_scb_lists[col_idx]; - free_tailq = &ahd->scb_data.free_scbs; - first_scb = LIST_FIRST(free_list); - if (first_scb != NULL) { - LIST_INSERT_AFTER(first_scb, scb, collision_links); - } else { - LIST_INSERT_HEAD(free_list, scb, collision_links); - TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe); - } -} - -void -ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb) -{ - struct scb_list *free_list; - struct scb_tailq *free_tailq; - struct scb *first_scb; - u_int col_idx; - - scb->flags &= ~SCB_ON_COL_LIST; - col_idx = AHD_GET_SCB_COL_IDX(ahd, scb); - free_list = &ahd->scb_data.free_scb_lists[col_idx]; - free_tailq = &ahd->scb_data.free_scbs; - first_scb = LIST_FIRST(free_list); - if (first_scb == scb) { - struct scb *next_scb; - - /* - * Maintain order in the collision free - * lists for fairness if this device has - * other colliding tags active. - */ - next_scb = LIST_NEXT(scb, collision_links); - if (next_scb != NULL) { - TAILQ_INSERT_AFTER(free_tailq, scb, - next_scb, links.tqe); - } - TAILQ_REMOVE(free_tailq, scb, links.tqe); - } - LIST_REMOVE(scb, collision_links); -} - /* * Get a free scb. If there are none, see if we can allocate a new SCB. */ struct scb * -ahd_get_scb(struct ahd_softc *ahd, u_int col_idx) +ahd_get_scb(struct ahd_softc *ahd) { struct scb *scb; - TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { - if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) { - ahd_rem_col_list(ahd, scb); - goto found; - } - } if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) { /* All scb's are allocated at initialization in OpenBSD. */ return (NULL); } LIST_REMOVE(scb, links.le); - if (col_idx != AHD_NEVER_COL_IDX - && (scb->col_scb != NULL) - && (scb->col_scb->flags & SCB_ACTIVE) == 0) { - LIST_REMOVE(scb->col_scb, links.le); - ahd_add_col_list(ahd, scb->col_scb, col_idx); - } -found: scb->flags |= SCB_ACTIVE; return (scb); } @@ -5898,46 +5829,7 @@ ahd_free_scb(struct ahd_softc *ahd, stru scb->hscb->control = 0; ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL; - if (scb->col_scb == NULL) { - - /* - * No collision possible. Just free normally. - */ - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb, links.le); - } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) { - - /* - * The SCB we might have collided with is on - * a free collision list. Put both SCBs on - * the generic list. - */ - ahd_rem_col_list(ahd, scb->col_scb); - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb, links.le); - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb->col_scb, links.le); - } else if ((scb->col_scb->flags - & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE - && (scb->col_scb->hscb->control & TAG_ENB) != 0) { - - /* - * The SCB we might collide with on the next allocation - * is still active in a non-packetized, tagged, context. - * Put us on the SCB collision list. - */ - ahd_add_col_list(ahd, scb, - AHD_GET_SCB_COL_IDX(ahd, scb->col_scb)); - } else { - /* - * The SCB we might collide with on the next allocation - * is either active in a packetized context, or free. - * Since we can't collide, put this SCB on the generic - * free list. - */ - LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, - scb, links.le); - } + LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list, scb, links.le); aic_platform_scb_free(ahd, scb); } @@ -6070,7 +5962,6 @@ ahd_alloc_scbs(struct ahd_softc *ahd) scb_data->sgs_left -= newcount; for (i = 0; i < newcount; i++) { struct scb_platform_data *pdata = NULL; - u_int col_tag; #ifndef __linux__ int error; #endif @@ -6123,10 +6014,6 @@ ahd_alloc_scbs(struct ahd_softc *ahd) break; } next_scb->hscb->tag = aic_htole16(scb_data->numscbs); - col_tag = scb_data->numscbs ^ 0x100; - next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag); - if (next_scb->col_scb != NULL) - next_scb->col_scb->col_scb = next_scb; ahd_free_scb(ahd, next_scb); hscb++; hscb_busaddr += sizeof(*hscb); Index: aic79xx.h =================================================================== RCS file: /cvs/src/sys/dev/ic/aic79xx.h,v retrieving revision 1.21 diff -u -p -r1.21 aic79xx.h --- aic79xx.h 21 Dec 2006 02:28:47 -0000 1.21 +++ aic79xx.h 5 Apr 2011 12:19:20 -0000 @@ -157,26 +157,6 @@ struct scb_platform_data; #define AHD_TMODE_ENABLE 0 #endif -#define AHD_BUILD_COL_IDX(target, lun) \ - (((lun) << 4) | target) - -#define AHD_GET_SCB_COL_IDX(ahd, scb) \ - ((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb)) - -#define AHD_SET_SCB_COL_IDX(scb, col_idx) \ -do { \ - (scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID; \ - (scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1); \ -} while (0) - -#define AHD_COPY_SCB_COL_IDX(dst, src) \ -do { \ - dst->hscb->scsiid = src->hscb->scsiid; \ - dst->hscb->lun = src->hscb->lun; \ -} while (0) - -#define AHD_NEVER_COL_IDX 0xFFFF - /**************************** Driver Constants ********************************/ /* * The maximum number of supported targets. @@ -651,7 +631,6 @@ struct scb { #define pending_links links2.le #define collision_links links2.le LIST_ENTRY(scb) timedout_links; - struct scb *col_scb; struct scsi_xfer *xs; struct ahd_softc *ahd_softc; @@ -1423,7 +1402,7 @@ void ahd_softc_insert(struct ahd_soft struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd); void ahd_set_unit(struct ahd_softc *, int); void ahd_set_name(struct ahd_softc *, char *); -struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); +struct scb *ahd_get_scb(struct ahd_softc *ahd); void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); void ahd_alloc_scbs(struct ahd_softc *ahd); void ahd_free(struct ahd_softc *ahd); Index: aic79xx_openbsd.c =================================================================== RCS file: /cvs/src/sys/dev/ic/aic79xx_openbsd.c,v retrieving revision 1.37 diff -u -p -r1.37 aic79xx_openbsd.c --- aic79xx_openbsd.c 28 Jun 2010 18:31:02 -0000 1.37 +++ aic79xx_openbsd.c 5 Apr 2011 12:19:20 -0000 @@ -291,7 +291,6 @@ ahd_action(struct scsi_xfer *xs) int s; struct ahd_initiator_tinfo *tinfo; struct ahd_tmode_tstate *tstate; - u_int col_idx; u_int16_t quirks; SC_DEBUG(xs->sc_link, SDEV_DB3, ("ahd_action\n")); @@ -314,13 +313,7 @@ ahd_action(struct scsi_xfer *xs) quirks = xs->sc_link->quirks; - if ((quirks & SDEV_NOTAGS) != 0 || - (tinfo->curr.ppr_options & MSG_EXT_PPR_PROT_IUS) != 0) - col_idx = AHD_NEVER_COL_IDX; - else - col_idx = AHD_BUILD_COL_IDX(target_id, xs->sc_link->lun); - - if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { + if ((scb = ahd_get_scb(ahd)) == NULL) { ahd->flags |= AHD_RESOURCE_SHORTAGE; xs->error = XS_NO_CCB; scsi_done(xs);