From: krw Date: Wed, 17 Aug 2016 01:16:11 +0000 (+0000) Subject: Move to iopool. No voluntary testers after several years of requests so now X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=94b57586ec0fa655aebc4ab8425d9158f7c7d5ee;p=openbsd Move to iopool. No voluntary testers after several years of requests so now everybody gets to test! --- diff --git a/sys/dev/ic/aic79xx.c b/sys/dev/ic/aic79xx.c index 6cc466f176b..0a7124504c5 100644 --- a/sys/dev/ic/aic79xx.c +++ b/sys/dev/ic/aic79xx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aic79xx.c,v 1.60 2016/03/15 20:50:22 krw Exp $ */ +/* $OpenBSD: aic79xx.c,v 1.61 2016/08/17 01:16:11 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -212,10 +212,6 @@ struct scb * ahd_find_scb_by_tag(struct ahd_softc *, u_int); 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, @@ -3398,7 +3394,7 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) * active transaction on the bus. */ pending_scb_count = 0; - LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(pending_scb, &ahd->pending_scbs, next) { struct ahd_devinfo devinfo; struct ahd_initiator_tinfo *tinfo; struct ahd_tmode_tstate *tstate; @@ -3442,7 +3438,7 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); saved_scbptr = ahd_get_scbptr(ahd); /* Ensure that the hscbs down on the card match the new information */ - LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(pending_scb, &ahd->pending_scbs, next) { u_int scb_tag; u_int control; @@ -5252,7 +5248,7 @@ ahd_alloc(void *platform_arg, char *name) if (ahd->seep_config == NULL) return (NULL); - LIST_INIT(&ahd->pending_scbs); + TAILQ_INIT(&ahd->pending_scbs); LIST_INIT(&ahd->timedout_scbs); /* We don't know our unit number until the OSM sets it */ @@ -5612,12 +5608,11 @@ ahd_init_scbdata(struct ahd_softc *ahd) scb_data = &ahd->scb_data; TAILQ_INIT(&scb_data->free_scbs); - for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++) - LIST_INIT(&scb_data->free_scb_lists[i]); - LIST_INIT(&scb_data->any_dev_free_scb_list); SLIST_INIT(&scb_data->hscb_maps); SLIST_INIT(&scb_data->sg_maps); SLIST_INIT(&scb_data->sense_maps); + mtx_init(&ahd->sc_scb_mtx, IPL_BIO); + scsi_iopool_init(&ahd->sc_iopool, ahd, ahd_scb_alloc, ahd_scb_free); /* Determine the number of hardware SCBs and initialize them */ scb_data->maxhscbs = ahd_probe_scbs(ahd); @@ -5670,29 +5665,15 @@ ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag) /* * Look on the pending list. */ - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(scb, &ahd->pending_scbs, next) { if (SCB_GET_TAG(scb) == tag) return (scb); } - /* - * Then on all of the collision free lists. - */ - TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { - struct scb *list_scb; - - list_scb = scb; - do { - if (SCB_GET_TAG(list_scb) == tag) - return (list_scb); - list_scb = LIST_NEXT(list_scb, collision_links); - } while (list_scb); - } - /* * And finally on the generic free list. */ - LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, next) { if (SCB_GET_TAG(scb) == tag) return (scb); } @@ -5801,85 +5782,23 @@ ahd_iocell_first_selection(struct ahd_softc *ahd) 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) +void * +ahd_scb_alloc(void *xahd) { + struct ahd_softc *ahd = xahd; 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; - } + mtx_enter(&ahd->sc_scb_mtx); + scb = TAILQ_FIRST(&ahd->scb_data.free_scbs); + if (scb) { + TAILQ_REMOVE(&ahd->scb_data.free_scbs, scb, next); + scb->flags |= SCB_ACTIVE; } - 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; + mtx_leave(&ahd->sc_scb_mtx); + return (scb); } @@ -5887,56 +5806,20 @@ found: * Return an SCB resource to the free list. */ void -ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) +ahd_scb_free(void *xahd, void *xscb) { + struct ahd_softc *ahd = xahd; + struct scb *scb = xscb; /* Clean up for the next user */ scb->flags = SCB_FLAG_NONE; 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); - } - + mtx_enter(&ahd->sc_scb_mtx); + TAILQ_INSERT_HEAD(&ahd->scb_data.free_scbs, scb, next); aic_platform_scb_free(ahd, scb); + mtx_leave(&ahd->sc_scb_mtx); } void @@ -6067,7 +5950,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; int error; next_scb = (struct scb *)malloc(sizeof(*next_scb), @@ -6118,11 +6000,7 @@ 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); + ahd_scb_free(ahd, next_scb); hscb++; hscb_busaddr += sizeof(*hscb); segs += ahd_sglist_size(ahd); @@ -7011,7 +6889,7 @@ ahd_suspend(struct ahd_softc *ahd) ahd_pause_and_flushwork(ahd); - if (LIST_FIRST(&ahd->pending_scbs) != NULL) { + if (!TAILQ_EMPTY(&ahd->pending_scbs)) { ahd_unpause(ahd); return (EBUSY); } @@ -7217,7 +7095,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd) ahd_flush_qoutfifo(ahd); pending_cmds = 0; - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(scb, &ahd->pending_scbs, next) { pending_cmds++; } ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd)); @@ -7698,10 +7576,10 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, * These are other tagged commands that were * disconnected when the reset occurred. */ - scbp_next = LIST_FIRST(&ahd->pending_scbs); + scbp_next = TAILQ_FIRST(&ahd->pending_scbs); while (scbp_next != NULL) { scbp = scbp_next; - scbp_next = LIST_NEXT(scbp, pending_links); + scbp_next = TAILQ_NEXT(scbp, next); if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) { cam_status ostat; @@ -8909,7 +8787,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) saved_scb_index = ahd_get_scbptr(ahd); printf("Pending list:"); i = 0; - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(scb, &ahd->pending_scbs, next) { if (i++ > AHD_SCB_MAX) break; cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb), @@ -8924,19 +8802,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) printf("Kernel Free SCB list: "); i = 0; - TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) { - struct scb *list_scb; - - list_scb = scb; - do { - printf("%d ", SCB_GET_TAG(list_scb)); - list_scb = LIST_NEXT(list_scb, collision_links); - } while (list_scb && i++ < AHD_SCB_MAX); - } - - LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) { - if (i++ > AHD_SCB_MAX) - break; + TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, next) { printf("%d ", SCB_GET_TAG(scb)); } printf("\n"); @@ -9147,7 +9013,7 @@ ahd_timeout(void *arg) * timeouts for them. They're about to be aborted so no need * for them to timeout. */ - LIST_FOREACH(list_scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(list_scb, &ahd->pending_scbs, next) { if (list_scb->xs) timeout_del(&list_scb->xs->stimeout); } @@ -9682,7 +9548,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) ahd_lock(ahd, &s); ccb->ccb_h.status = CAM_REQ_CMP; - LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { + TAILQ_FOREACH(scb, &ahd->pending_scbs, next) { struct ccb_hdr *ccbh; ccbh = &scb->io_ctx->ccb_h; diff --git a/sys/dev/ic/aic79xx.h b/sys/dev/ic/aic79xx.h index a298b4abe22..2db84c48e79 100644 --- a/sys/dev/ic/aic79xx.h +++ b/sys/dev/ic/aic79xx.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aic79xx.h,v 1.25 2015/12/17 19:35:24 tedu Exp $ */ +/* $OpenBSD: aic79xx.h,v 1.26 2016/08/17 01:16:11 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -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. @@ -637,21 +617,9 @@ typedef enum { } scb_flag; struct scb { + TAILQ_ENTRY(scb) next; struct hardware_scb *hscb; - union { - SLIST_ENTRY(scb) sle; - LIST_ENTRY(scb) le; - TAILQ_ENTRY(scb) tqe; - } links; - union { - SLIST_ENTRY(scb) sle; - LIST_ENTRY(scb) le; - TAILQ_ENTRY(scb) tqe; - } links2; -#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; @@ -674,22 +642,10 @@ TAILQ_HEAD(scb_tailq, scb); LIST_HEAD(scb_list, scb); struct scb_data { - /* - * TAILQ of lists of free SCBs grouped by device - * collision domains. - */ - struct scb_tailq free_scbs; - - /* - * Per-device lists of SCBs whose tag ID would collide - * with an already active tag on the device. - */ - struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT]; - /* * SCBs that will not collide with any active device. */ - struct scb_list any_dev_free_scb_list; + struct scb_tailq free_scbs; /* * Mapping from tag to SCB. @@ -1109,13 +1065,16 @@ struct ahd_softc { /* * SCBs that have been sent to the controller */ - LIST_HEAD(, scb) pending_scbs; + TAILQ_HEAD(, scb) pending_scbs; /* * SCBs whose timeout routine has been called. */ LIST_HEAD(, scb) timedout_scbs; + struct mutex sc_scb_mtx; + struct scsi_iopool sc_iopool; + /* * Current register window mode information. */ @@ -1418,8 +1377,8 @@ void ahd_softc_insert(struct ahd_softc *); 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); -void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); +void *ahd_scb_alloc(void *); +void ahd_scb_free(void *, void *); void ahd_alloc_scbs(struct ahd_softc *ahd); void ahd_free(struct ahd_softc *ahd); int ahd_reset(struct ahd_softc *ahd, int reinit); diff --git a/sys/dev/ic/aic79xx_openbsd.c b/sys/dev/ic/aic79xx_openbsd.c index c396b30fdff..56879844fef 100644 --- a/sys/dev/ic/aic79xx_openbsd.c +++ b/sys/dev/ic/aic79xx_openbsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aic79xx_openbsd.c,v 1.44 2016/03/19 11:34:22 mpi Exp $ */ +/* $OpenBSD: aic79xx_openbsd.c,v 1.45 2016/08/17 01:16:11 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -112,7 +112,8 @@ ahd_attach(struct ahd_softc *ahd) ahd->sc_channel.adapter_buswidth = 16; ahd->sc_channel.adapter_softc = ahd; ahd->sc_channel.adapter = &ahd_switch; - ahd->sc_channel.openings = 16; + ahd->sc_channel.openings = 16; /* Must ALWAYS be < 256!! */ + ahd->sc_channel.pool = &ahd->sc_iopool; if (bootverbose) { ahd_controller_info(ahd, ahd_info, sizeof ahd_info); @@ -158,11 +159,10 @@ void ahd_done(struct ahd_softc *ahd, struct scb *scb) { struct scsi_xfer *xs = scb->xs; - int s; /* XXX in ahc there is some bus_dmamap_sync(PREREAD|PREWRITE); */ - LIST_REMOVE(scb, pending_links); + TAILQ_REMOVE(&ahd->pending_scbs, scb, next); timeout_del(&xs->stimeout); @@ -249,10 +249,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) xs->error = XS_SENSE; } - ahd_lock(ahd, &s); - ahd_free_scb(ahd, scb); scsi_done(xs); - ahd_unlock(ahd, &s); } void @@ -282,7 +279,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")); @@ -305,22 +301,13 @@ 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) { - ahd->flags |= AHD_RESOURCE_SHORTAGE; - xs->error = XS_NO_CCB; - scsi_done(xs); - ahd_unlock(ahd, &s); - return; - } ahd_unlock(ahd, &s); + scb = xs->io; hscb = scb->hscb; + scb->flags = SCB_FLAG_NONE; + scb->hscb->control = 0; + ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL; SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb)); @@ -398,7 +385,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments) if (nsegments != 0) bus_dmamap_unload(ahd->parent_dmat, scb->dmamap); - ahd_free_scb(ahd, scb); ahd_unlock(ahd, &s); return; } @@ -429,7 +415,7 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments) /* XXX with ahc there was some bus_dmamap_sync(PREREAD|PREWRITE); */ - LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); + TAILQ_INSERT_HEAD(&ahd->pending_scbs, scb, next); if (!(xs->flags & SCSI_POLL)) timeout_add_msec(&xs->stimeout, xs->timeout); @@ -507,7 +493,6 @@ ahd_setup_data(struct ahd_softc *ahd, struct scsi_xfer *xs, struct scb *scb) { struct hardware_scb *hscb; - int s; hscb = scb->hscb; xs->resid = xs->status = 0; @@ -515,11 +500,8 @@ ahd_setup_data(struct ahd_softc *ahd, struct scsi_xfer *xs, hscb->cdb_len = xs->cmdlen; if (hscb->cdb_len > MAX_CDB_LEN) { - ahd_lock(ahd, &s); - ahd_free_scb(ahd, scb); xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); - ahd_unlock(ahd, &s); return; } @@ -542,11 +524,8 @@ ahd_setup_data(struct ahd_softc *ahd, struct scsi_xfer *xs, printf("%s: in ahd_setup_data(): bus_dmamap_load() " "= %d\n", ahd_name(ahd), error); #endif - ahd_lock(ahd, &s); - ahd_free_scb(ahd, scb); xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); - ahd_unlock(ahd, &s); return; } ahd_execute_scb(scb, scb->dmamap->dm_segs,