-/* $OpenBSD: aic7xxx.c,v 1.91 2015/07/17 21:42:49 krw Exp $ */
+/* $OpenBSD: aic7xxx.c,v 1.92 2016/08/17 01:17:54 krw Exp $ */
/* $NetBSD: aic7xxx.c,v 1.108 2003/11/02 11:07:44 wiz Exp $ */
/*
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: aic7xxx.c,v 1.91 2015/07/17 21:42:49 krw Exp $
+ * $Id: aic7xxx.c,v 1.92 2016/08/17 01:17:54 krw Exp $
*/
/*
* Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
SLIST_INIT(&scb_data->free_scbs);
SLIST_INIT(&scb_data->sg_maps);
+ mtx_init(&ahc->sc_scb_mtx, IPL_BIO);
+ scsi_iopool_init(&ahc->sc_iopool, ahc, ahc_scb_alloc, ahc_scb_free);
+
/* Allocate SCB resources */
scb_data->scbarray = mallocarray(AHC_SCB_MAX_ALLOC, sizeof(struct scb),
M_DEVBUF, M_NOWAIT | M_ZERO);
/*
* Reserve the next queued SCB.
*/
- ahc->next_queued_scb = ahc_get_scb(ahc);
-
- /*
- * Note that we were successful
- */
- return (0);
+ ahc->next_queued_scb = scsi_io_get(&ahc->sc_iopool,
+ SCSI_POLL | SCSI_NOSLEEP);
+ if (ahc->next_queued_scb != NULL)
+ /* Note that we were successful */
+ return (0);
error_exit:
next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
next_scb->hscb->tag = ahc->scb_data->numscbs;
+ mtx_enter(&ahc->sc_scb_mtx);
SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
next_scb, links.sle);
+ mtx_leave(&ahc->sc_scb_mtx);
segs += AHC_NSEG;
physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
next_scb++;
printf("Kernel Free SCB list: ");
i = 0;
+ mtx_enter(&ahc->sc_scb_mtx);
SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
if (i++ > 256)
break;
printf("%d ", scb->hscb->tag);
}
printf("\n");
+ mtx_leave(&ahc->sc_scb_mtx);
maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
for (target = 0; target <= maxtarget; target++) {
-/* $OpenBSD: aic7xxx_inline.h,v 1.16 2015/07/17 21:42:49 krw Exp $ */
+/* $OpenBSD: aic7xxx_inline.h,v 1.17 2016/08/17 01:17:54 krw Exp $ */
/* $NetBSD: aic7xxx_inline.h,v 1.4 2003/11/02 11:07:44 wiz Exp $ */
/*
ahc_inl(struct ahc_softc *ahc, u_int port);
IO_INLINE void ahc_outl(struct ahc_softc *ahc, u_int port,
uint32_t value);
-IO_INLINE struct scb*
- ahc_get_scb(struct ahc_softc *ahc);
-IO_INLINE void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb);
IO_INLINE struct scb *ahc_lookup_scb(struct ahc_softc *ahc, u_int tag);
IO_INLINE void ahc_swap_with_next_hscb(struct ahc_softc *ahc,
struct scb *scb);
ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);
}
-/*
- * Get a free scb. If there are none, see if we can allocate a new SCB.
- */
-IO_INLINE struct scb *
-ahc_get_scb(struct ahc_softc *ahc)
-{
- struct scb *scb;
-
- scb = SLIST_FIRST(&ahc->scb_data->free_scbs);
-
- if (scb != NULL)
- SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);
-
- return (scb);
-}
-
-/*
- * Return an SCB resource to the free list.
- */
-IO_INLINE void
-ahc_free_scb(struct ahc_softc *ahc, struct scb *scb)
-{
- struct hardware_scb *hscb;
-
- hscb = scb->hscb;
- /* Clean up for the next user */
- ahc->scb_data->scbindex[hscb->tag] = NULL;
- scb->flags = SCB_FLAG_NONE;
- hscb->control = 0;
-
- SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
-
- /* Notify the OSM that a resource is now available. */
- ahc_platform_scb_free(ahc, scb);
-}
-
-
IO_INLINE struct scb *
ahc_lookup_scb(struct ahc_softc *ahc, u_int tag)
{
-/* $OpenBSD: aic7xxx_openbsd.c,v 1.54 2015/07/17 21:42:49 krw Exp $ */
+/* $OpenBSD: aic7xxx_openbsd.c,v 1.55 2016/08/17 01:17:54 krw Exp $ */
/* $NetBSD: aic7xxx_osm.c,v 1.14 2003/11/02 11:07:44 wiz Exp $ */
/*
ahc->sc_channel.adapter_softc = ahc;
ahc->sc_channel.adapter = &ahc_switch;
ahc->sc_channel.openings = 16;
+ ahc->sc_channel.pool = &ahc->sc_iopool;
if (ahc->features & AHC_TWIN) {
/* Configure the second scsi bus */
ahc_done(struct ahc_softc *ahc, struct scb *scb)
{
struct scsi_xfer *xs = scb->xs;
- int s;
bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
0, ahc->scb_data->hscb_dmamap->dm_mapsize,
xs->error = XS_SENSE;
}
- s = splbio();
- ahc_free_scb(ahc, scb);
scsi_done(xs);
- splx(s);
}
void
struct hardware_scb *hscb;
u_int target_id;
u_int our_id;
- int s;
SC_DEBUG(xs->sc_link, SDEV_DB3, ("ahc_action\n"));
ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
our_id = SCSI_SCSI_ID(ahc, xs->sc_link);
/*
- * get an scb to use.
+ * get the scb to use.
*/
- s = splbio();
- scb = ahc_get_scb(ahc);
- splx(s);
- if (scb == NULL) {
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- return;
- }
+ scb = xs->io;
+
+ /* Clean up for the next user */
+ scb->flags = SCB_FLAG_NONE;
hscb = scb->hscb;
+ hscb->control = 0;
+ ahc->scb_data->scbindex[hscb->tag] = NULL;
SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb));
scb->xs = xs;
struct scb *scb)
{
struct hardware_scb *hscb;
- int s;
hscb = scb->hscb;
xs->resid = xs->status = 0;
hscb->cdb_len = xs->cmdlen;
if (hscb->cdb_len > sizeof(hscb->cdb32)) {
- s = splbio();
- ahc_free_scb(ahc, scb);
- splx(s);
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
return;
"= %d\n",
ahc_name(ahc), error);
#endif
- s = splbio();
- ahc_free_scb(ahc, scb);
- splx(s);
xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
return;
splx(s);
}
+
+/*
+ * Get a free scb. If there are none, see if we can allocate a new SCB.
+ */
+void *
+ahc_scb_alloc(void *xahc)
+{
+ struct ahc_softc *ahc = xahc;
+ struct scb *scb;
+
+ mtx_enter(&ahc->sc_scb_mtx);
+ scb = SLIST_FIRST(&ahc->scb_data->free_scbs);
+
+ if (scb != NULL)
+ SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);
+
+ mtx_leave(&ahc->sc_scb_mtx);
+
+ return (scb);
+}
+
+/*
+ * Return an SCB resource to the free list.
+ */
+void
+ahc_scb_free(void *xahc, void *io)
+{
+ struct ahc_softc *ahc = xahc;
+ struct scb *scb = io;
+ struct hardware_scb *hscb;
+
+ hscb = scb->hscb;
+ /* Clean up for the next user */
+ ahc->scb_data->scbindex[hscb->tag] = NULL;
+ scb->flags = SCB_FLAG_NONE;
+ hscb->control = 0;
+
+ mtx_enter(&ahc->sc_scb_mtx);
+ SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
+ mtx_leave(&ahc->sc_scb_mtx);
+
+ /* Notify the OSM that a resource is now available. */
+ ahc_platform_scb_free(ahc, scb);
+}
-/* $OpenBSD: aic7xxx_openbsd.h,v 1.25 2015/07/17 21:42:49 krw Exp $ */
+/* $OpenBSD: aic7xxx_openbsd.h,v 1.26 2016/08/17 01:17:54 krw Exp $ */
/* $NetBSD: aic7xxx_osm.h,v 1.7 2003/11/02 11:07:44 wiz Exp $ */
/*
void ahc_done(struct ahc_softc *, struct scb *);
void ahc_send_async(struct ahc_softc *, char, u_int, u_int, ac_code,
void *);
+void *ahc_scb_alloc(void *);
+void ahc_scb_free(void *, void *);
#endif /* _AIC7XXX_OPENBSD_H_ */
-/* $OpenBSD: aic7xxxvar.h,v 1.29 2015/12/17 19:35:24 tedu Exp $ */
+/* $OpenBSD: aic7xxxvar.h,v 1.30 2016/08/17 01:17:54 krw Exp $ */
/*
* Core definitions and data structures shareable across OS platforms.
*
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: aic7xxxvar.h,v 1.29 2015/12/17 19:35:24 tedu Exp $
+ * $Id: aic7xxxvar.h,v 1.30 2016/08/17 01:17:54 krw Exp $
*
* $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.50 2003/12/17 00:02:09 gibbs Exp $
*/
bus_space_tag_t tag;
bus_space_handle_t bsh;
+ struct mutex sc_scb_mtx;
+ struct scsi_iopool sc_iopool;
+
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
struct scb_data *scb_data;