[Midnightbsd-cvs] src [9462] trunk/sys/dev: Modernize and lock the aha, ahb, adv, adw, bt, and dpt drivers.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sun Mar 5 14:38:54 EST 2017
Revision: 9462
http://svnweb.midnightbsd.org/src/?rev=9462
Author: laffer1
Date: 2017-03-05 14:38:53 -0500 (Sun, 05 Mar 2017)
Log Message:
-----------
Modernize and lock the aha, ahb, adv, adw, bt, and dpt drivers.
Modified Paths:
--------------
trunk/sys/dev/advansys/adv_eisa.c
trunk/sys/dev/advansys/adv_isa.c
trunk/sys/dev/advansys/adv_pci.c
trunk/sys/dev/advansys/advansys.c
trunk/sys/dev/advansys/advansys.h
trunk/sys/dev/advansys/advlib.c
trunk/sys/dev/advansys/advlib.h
trunk/sys/dev/advansys/adw_pci.c
trunk/sys/dev/advansys/adwcam.c
trunk/sys/dev/advansys/adwlib.c
trunk/sys/dev/advansys/adwlib.h
trunk/sys/dev/advansys/adwvar.h
trunk/sys/dev/aha/aha.c
trunk/sys/dev/aha/aha_isa.c
trunk/sys/dev/aha/aha_mca.c
trunk/sys/dev/aha/ahareg.h
trunk/sys/dev/ahb/ahb.c
trunk/sys/dev/ahb/ahbreg.h
trunk/sys/dev/buslogic/bt.c
trunk/sys/dev/buslogic/bt_eisa.c
trunk/sys/dev/buslogic/bt_isa.c
trunk/sys/dev/buslogic/bt_mca.c
trunk/sys/dev/buslogic/bt_pci.c
trunk/sys/dev/buslogic/btreg.h
trunk/sys/dev/dpt/dpt.h
trunk/sys/dev/dpt/dpt_eisa.c
trunk/sys/dev/dpt/dpt_isa.c
trunk/sys/dev/dpt/dpt_pci.c
trunk/sys/dev/dpt/dpt_scsi.c
Modified: trunk/sys/dev/advansys/adv_eisa.c
===================================================================
--- trunk/sys/dev/advansys/adv_eisa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adv_eisa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adv_eisa.c,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Device probe and attach routines for the following
* Advanced Systems Inc. SCSI controllers:
@@ -132,17 +132,27 @@
return 0;
}
+/*
+ * The adv_b stuff to handle twin-channel cards will not work in its current
+ * incarnation. It tries to reuse the same softc since adv_alloc() doesn't
+ * actually allocate a softc. It also tries to reuse the same unit number
+ * for both sims. This can be re-enabled if someone fixes it properly.
+ */
static int
adv_eisa_attach(device_t dev)
{
struct adv_softc *adv;
+#if 0
struct adv_softc *adv_b;
+#endif
struct resource *io;
struct resource *irq;
int rid, error;
void *ih;
+#if 0
adv_b = NULL;
+#endif
rid = 0;
io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
@@ -163,8 +173,8 @@
switch (eisa_get_id(dev) & ~0xF) {
case EISA_DEVICE_ID_ADVANSYS_750:
- adv_b = adv_alloc(dev, rman_get_bustag(io),
- rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN2);
+#if 0
+ adv_b = adv_alloc(dev, io, ADV_EISA_OFFSET_CHAN2);
if (adv_b == NULL)
goto bad;
@@ -184,26 +194,28 @@
/* nsegments */ ~0,
/* maxsegsz */ ADV_EISA_MAX_DMA_COUNT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adv_b->parent_dmat);
if (error != 0) {
- printf("%s: Could not allocate DMA tag - error %d\n",
- adv_name(adv_b), error);
+ device_printf(dev, "Could not allocate DMA tag - error %d\n",
+ error);
adv_free(adv_b);
goto bad;
}
adv_b->init_level++;
+#endif
/* FALLTHROUGH */
case EISA_DEVICE_ID_ADVANSYS_740:
- adv = adv_alloc(dev, rman_get_bustag(io),
- rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN1);
+ adv = adv_alloc(dev, io, ADV_EISA_OFFSET_CHAN1);
if (adv == NULL) {
+#if 0
if (adv_b != NULL)
adv_free(adv_b);
+#endif
goto bad;
}
@@ -223,13 +235,13 @@
/* nsegments */ ~0,
/* maxsegsz */ ADV_EISA_MAX_DMA_COUNT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adv->parent_dmat);
if (error != 0) {
- printf("%s: Could not allocate DMA tag - error %d\n",
- adv_name(adv), error);
+ device_printf(dev, "Could not allocate DMA tag - error %d\n",
+ error);
adv_free(adv);
goto bad;
}
@@ -245,7 +257,7 @@
if (overrun_buf == NULL) {
/* Need to allocate our overrun buffer */
if (bus_dma_tag_create(
- /* parent */ adv->parent_dmat,
+ /* parent */ bus_get_dma_tag(dev),
/* alignment */ 8,
/* boundary */ 0,
/* lowaddr */ ADV_EISA_MAX_DMA_ADDR,
@@ -256,8 +268,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&overrun_dmat) != 0) {
adv_free(adv);
goto bad;
@@ -293,14 +305,17 @@
if (adv_init(adv) != 0) {
adv_free(adv);
+#if 0
if (adv_b != NULL)
adv_free(adv_b);
- return(-1);
+#endif
+ goto bad;
}
adv->max_dma_count = ADV_EISA_MAX_DMA_COUNT;
adv->max_dma_addr = ADV_EISA_MAX_DMA_ADDR;
+#if 0
if (adv_b != NULL) {
/*
* Stop the chip.
@@ -318,17 +333,26 @@
adv_b->max_dma_addr = ADV_EISA_MAX_DMA_ADDR;
}
}
+#endif
/*
* Enable our interrupt handler.
*/
- bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY, NULL, adv_intr,
- adv, &ih);
+ if (bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL,
+ adv_intr, adv, &ih) != 0) {
+ adv_free(adv);
+ goto bad;
+ }
- /* Attach sub-devices - always succeeds */
- adv_attach(adv);
+ /* Attach sub-devices */
+ if (adv_attach(adv) != 0) {
+ adv_free(adv);
+ goto bad;
+ }
+#if 0
if (adv_b != NULL)
adv_attach(adv_b);
+#endif
return 0;
@@ -335,7 +359,7 @@
bad:
bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
- return -1;
+ return ENXIO;
}
static device_method_t adv_eisa_methods[] = {
Modified: trunk/sys/dev/advansys/adv_isa.c
===================================================================
--- trunk/sys/dev/advansys/adv_isa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adv_isa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adv_isa.c,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Device probe and attach routines for the following
* Advanced Systems Inc. SCSI controllers:
@@ -136,12 +136,13 @@
if ((port_index > max_port_index)
|| (iobase != adv_isa_ioports[port_index])) {
if (bootverbose)
- printf("adv%d: Invalid baseport of 0x%lx specified. "
- "Nearest valid baseport is 0x%x. Failing "
- "probe.\n", device_get_unit(dev), iobase,
- (port_index <= max_port_index) ?
- adv_isa_ioports[port_index] :
- adv_isa_ioports[max_port_index]);
+ device_printf(dev,
+ "Invalid baseport of 0x%lx specified. "
+ "Nearest valid baseport is 0x%x. Failing "
+ "probe.\n", iobase,
+ (port_index <= max_port_index) ?
+ adv_isa_ioports[port_index] :
+ adv_isa_ioports[max_port_index]);
return ENXIO;
}
max_port_index = port_index;
@@ -170,8 +171,7 @@
if (iores == NULL)
continue;
- if (adv_find_signature(rman_get_bustag(iores),
- rman_get_bushandle(iores)) == 0) {
+ if (adv_find_signature(iores) == 0) {
bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
continue;
}
@@ -180,8 +180,7 @@
* Got one. Now allocate our softc
* and see if we can initialize the card.
*/
- adv = adv_alloc(dev, rman_get_bustag(iores),
- rman_get_bushandle(iores));
+ adv = adv_alloc(dev, iores, 0);
if (adv == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
break;
@@ -239,13 +238,13 @@
/* nsegments */ ~0,
/* maxsegsz */ maxsegsz,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adv->parent_dmat);
if (error != 0) {
- printf("%s: Could not allocate DMA tag - error %d\n",
- adv_name(adv), error);
+ device_printf(dev,
+ "Could not allocate DMA tag - error %d\n", error);
adv_free(adv);
bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
break;
@@ -336,8 +335,11 @@
irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (irqres == NULL ||
- bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY,
- NULL, adv_intr, adv, &ih)) {
+ bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|
+ INTR_MPSAFE, NULL, adv_intr, adv, &ih) != 0) {
+ if (irqres != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ, rid,
+ irqres);
bus_dmamap_unload(overrun_dmat, overrun_dmamap);
bus_dmamem_free(overrun_dmat, overrun_buf,
overrun_dmamap);
Modified: trunk/sys/dev/advansys/adv_pci.c
===================================================================
--- trunk/sys/dev/advansys/adv_pci.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adv_pci.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adv_pci.c,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Device probe and attach routines for the following
* Advanced Systems Inc. SCSI controllers:
@@ -139,7 +139,6 @@
{
struct adv_softc *adv;
u_int32_t id;
- u_int32_t command;
int error, rid, irqrid;
void *ih;
struct resource *iores, *irqres;
@@ -147,21 +146,10 @@
/*
* Determine the chip version.
*/
- id = pci_read_config(dev, PCIR_DEVVENDOR, /*bytes*/4);
- command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
+ id = pci_get_devid(dev);
+ pci_enable_busmaster(dev);
/*
- * These cards do not allow memory mapped accesses, so we must
- * ensure that I/O accesses are available or we won't be able
- * to talk to them.
- */
- if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
- != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
- command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
- pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
- }
-
- /*
* Early chips can't handle non-zero latency timer settings.
*/
if (id == PCI_DEVICE_ID_ADVANSYS_1200A
@@ -175,13 +163,12 @@
if (iores == NULL)
return ENXIO;
- if (adv_find_signature(rman_get_bustag(iores),
- rman_get_bushandle(iores)) == 0) {
+ if (adv_find_signature(iores) == 0) {
bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
return ENXIO;
}
- adv = adv_alloc(dev, rman_get_bustag(iores), rman_get_bushandle(iores));
+ adv = adv_alloc(dev, iores, 0);
if (adv == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
return ENXIO;
@@ -200,13 +187,13 @@
/* nsegments */ ~0,
/* maxsegsz */ ADV_PCI_MAX_DMA_COUNT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adv->parent_dmat);
if (error != 0) {
- printf("%s: Could not allocate DMA tag - error %d\n",
- adv_name(adv), error);
+ device_printf(dev, "Could not allocate DMA tag - error %d\n",
+ error);
adv_free(adv);
bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
return ENXIO;
@@ -228,8 +215,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&overrun_dmat) != 0) {
bus_dma_tag_destroy(adv->parent_dmat);
adv_free(adv);
@@ -309,14 +296,22 @@
irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqrid,
RF_SHAREABLE | RF_ACTIVE);
if (irqres == NULL ||
- bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY, NULL,
- adv_intr, adv, &ih)) {
+ bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE,
+ NULL, adv_intr, adv, &ih) != 0) {
+ if (irqres != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres);
adv_free(adv);
bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
return ENXIO;
}
- adv_attach(adv);
+ if (adv_attach(adv) != 0) {
+ bus_teardown_intr(dev, irqres, ih);
+ bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres);
+ adv_free(adv);
+ bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
+ return ENXIO;
+ }
return 0;
}
Modified: trunk/sys/dev/advansys/advansys.c
===================================================================
--- trunk/sys/dev/advansys/advansys.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/advansys.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/advansys.c,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Generic driver for the Advanced Systems Inc. SCSI controllers
* Product specific probe and attach routines can be found in:
@@ -50,6 +50,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
@@ -80,6 +81,7 @@
static void adv_action(struct cam_sim *sim, union ccb *ccb);
static void adv_execute_ccb(void *arg, bus_dma_segment_t *dm_segs,
int nsegments, int error);
+static void adv_intr_locked(struct adv_softc *adv);
static void adv_poll(struct cam_sim *sim);
static void adv_run_doneq(struct adv_softc *adv);
static struct adv_ccb_info *
@@ -98,15 +100,14 @@
adv_get_ccb_info(struct adv_softc *adv)
{
struct adv_ccb_info *cinfo;
- int opri;
- opri = splcam();
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
if ((cinfo = SLIST_FIRST(&adv->free_ccb_infos)) != NULL) {
SLIST_REMOVE_HEAD(&adv->free_ccb_infos, links);
} else {
cinfo = adv_alloc_ccb_info(adv);
}
- splx(opri);
return (cinfo);
}
@@ -114,12 +115,11 @@
static __inline void
adv_free_ccb_info(struct adv_softc *adv, struct adv_ccb_info *cinfo)
{
- int opri;
- opri = splcam();
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
cinfo->state = ACCB_FREE;
SLIST_INSERT_HEAD(&adv->free_ccb_infos, cinfo, links);
- splx(opri);
}
static __inline void
@@ -140,6 +140,9 @@
static void
adv_clear_state_really(struct adv_softc *adv, union ccb* ccb)
{
+
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
if ((adv->state & ADV_BUSDMA_BLOCK_CLEARED) != 0)
adv->state &= ~(ADV_BUSDMA_BLOCK_CLEARED|ADV_BUSDMA_BLOCK);
if ((adv->state & ADV_RESOURCE_SHORTAGE) != 0) {
@@ -165,13 +168,14 @@
*/
ccb_h = LIST_FIRST(&adv->pending_ccbs);
while (ccb_h != NULL) {
- ccb_h->timeout_ch =
- timeout(adv_timeout, (caddr_t)ccb_h,
- (ccb_h->timeout * hz) / 1000);
+ cinfo = ccb_h->ccb_cinfo_ptr;
+ callout_reset(&cinfo->timer,
+ ccb_h->timeout * hz / 1000, adv_timeout,
+ ccb_h);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
adv->state &= ~ADV_IN_TIMEOUT;
- printf("%s: No longer in timeout\n", adv_name(adv));
+ device_printf(adv->dev, "No longer in timeout\n");
}
}
if (adv->state == 0)
@@ -187,15 +191,6 @@
*physaddr = segs->ds_addr;
}
-char *
-adv_name(struct adv_softc *adv)
-{
- static char name[10];
-
- snprintf(name, sizeof(name), "adv%d", adv->unit);
- return (name);
-}
-
static void
adv_action(struct cam_sim *sim, union ccb *ccb)
{
@@ -204,6 +199,7 @@
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("adv_action\n"));
adv = (struct adv_softc *)cam_sim_softc(sim);
+ mtx_assert(&adv->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
/* Common cases first */
@@ -230,10 +226,8 @@
* to a single buffer
*/
if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
- int s;
int error;
- s = splsoftvm();
error =
bus_dmamap_load(adv->buffer_dmat,
cinfo->dmamap,
@@ -251,7 +245,6 @@
adv_set_state(adv,
ADV_BUSDMA_BLOCK);
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -300,7 +293,6 @@
target_bit_vector targ_mask;
struct adv_transinfo *tconf;
u_int update_type;
- int s;
cts = &ccb->cts;
targ_mask = ADV_TID_TO_TARGET_MASK(cts->ccb_h.target_id);
@@ -321,7 +313,6 @@
break;
}
- s = splcam();
scsi = &cts->proto_specific.scsi;
spi = &cts->xport_specific.spi;
if ((update_type & ADV_TRANS_GOAL) != 0) {
@@ -388,7 +379,6 @@
spi->sync_offset, update_type);
}
- splx(s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@@ -401,7 +391,6 @@
struct ccb_trans_settings *cts;
struct adv_transinfo *tconf;
target_bit_vector target_mask;
- int s;
cts = &ccb->cts;
target_mask = ADV_TID_TO_TARGET_MASK(cts->ccb_h.target_id);
@@ -417,7 +406,6 @@
scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
- s = splcam();
if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
tconf = &adv->tinfo[cts->ccb_h.target_id].current;
if ((adv->disc_enable & target_mask) != 0)
@@ -433,7 +421,6 @@
}
spi->sync_period = tconf->period;
spi->sync_offset = tconf->offset;
- splx(s);
spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
spi->valid = CTS_SPI_VALID_SYNC_RATE
| CTS_SPI_VALID_SYNC_OFFSET
@@ -455,13 +442,10 @@
}
case XPT_RESET_BUS: /* Reset the specified SCSI bus */
{
- int s;
- s = splcam();
adv_stop_execution(adv);
adv_reset_bus(adv, /*initiate_reset*/TRUE);
adv_start_execution(adv);
- splx(s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
@@ -522,7 +506,6 @@
struct adv_ccb_info *cinfo;
struct adv_scsi_q scsiq;
struct adv_sg_head sghead;
- int s;
csio = (struct ccb_scsiio *)arg;
ccb_h = &csio->ccb_h;
@@ -529,6 +512,8 @@
sim = xpt_path_sim(ccb_h->path);
adv = (struct adv_softc *)cam_sim_softc(sim);
cinfo = (struct adv_ccb_info *)csio->ccb_h.ccb_cinfo_ptr;
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
/*
* Setup our done routine to release the simq on
@@ -597,8 +582,6 @@
scsiq.sg_head = NULL;
}
- s = splcam();
-
/*
* Last time we need to check if this SCB needs to
* be aborted.
@@ -609,7 +592,6 @@
adv_clear_state(adv, (union ccb *)csio);
adv_free_ccb_info(adv, cinfo);
xpt_done((union ccb *)csio);
- splx(s);
return;
}
@@ -622,7 +604,6 @@
adv_clear_state(adv, (union ccb *)csio);
adv_free_ccb_info(adv, cinfo);
xpt_done((union ccb *)csio);
- splx(s);
return;
}
cinfo->state |= ACCB_ACTIVE;
@@ -629,9 +610,8 @@
ccb_h->status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&adv->pending_ccbs, ccb_h, sim_links.le);
/* Schedule our timeout */
- ccb_h->timeout_ch =
- timeout(adv_timeout, csio, (ccb_h->timeout * hz)/1000);
- splx(s);
+ callout_reset(&cinfo->timer, ccb_h->timeout * hz /1000, adv_timeout,
+ csio);
}
static struct adv_ccb_info *
@@ -642,11 +622,12 @@
cinfo = &adv->ccb_infos[adv->ccb_infos_allocated];
cinfo->state = ACCB_FREE;
+ callout_init_mtx(&cinfo->timer, &adv->lock, 0);
error = bus_dmamap_create(adv->buffer_dmat, /*flags*/0,
&cinfo->dmamap);
if (error != 0) {
- printf("%s: Unable to allocate CCB info "
- "dmamap - error %d\n", adv_name(adv), error);
+ device_printf(adv->dev, "Unable to allocate CCB info "
+ "dmamap - error %d\n", error);
return (NULL);
}
adv->ccb_infos_allocated++;
@@ -656,6 +637,8 @@
static void
adv_destroy_ccb_info(struct adv_softc *adv, struct adv_ccb_info *cinfo)
{
+
+ callout_drain(&cinfo->timer);
bus_dmamap_destroy(adv->buffer_dmat, cinfo->dmamap);
}
@@ -662,22 +645,20 @@
void
adv_timeout(void *arg)
{
- int s;
union ccb *ccb;
struct adv_softc *adv;
- struct adv_ccb_info *cinfo;
+ struct adv_ccb_info *cinfo, *cinfo2;
ccb = (union ccb *)arg;
adv = (struct adv_softc *)xpt_path_sim(ccb->ccb_h.path)->softc;
cinfo = (struct adv_ccb_info *)ccb->ccb_h.ccb_cinfo_ptr;
+ mtx_assert(&adv->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("Timed out\n");
- s = splcam();
/* Have we been taken care of already?? */
if (cinfo == NULL || cinfo->state == ACCB_FREE) {
- splx(s);
return;
}
@@ -703,7 +684,8 @@
ccb_h = LIST_FIRST(&adv->pending_ccbs);
while (ccb_h != NULL) {
- untimeout(adv_timeout, ccb_h, ccb_h->timeout_ch);
+ cinfo2 = ccb_h->ccb_cinfo_ptr;
+ callout_stop(&cinfo2->timer);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
@@ -714,8 +696,7 @@
adv_abort_ccb(adv, ccb->ccb_h.target_id,
ccb->ccb_h.target_lun, ccb,
CAM_CMD_TIMEOUT, /*queued_only*/FALSE);
- ccb->ccb_h.timeout_ch =
- timeout(adv_timeout, ccb, 2 * hz);
+ callout_reset(&cinfo->timer, 2 * hz, adv_timeout, ccb);
} else {
/* Our attempt to perform an abort failed, go for a reset */
xpt_print_path(ccb->ccb_h.path);
@@ -725,11 +706,10 @@
adv_reset_bus(adv, /*initiate_reset*/TRUE);
}
adv_start_execution(adv);
- splx(s);
}
struct adv_softc *
-adv_alloc(device_t dev, bus_space_tag_t tag, bus_space_handle_t bsh)
+adv_alloc(device_t dev, struct resource *res, long offset)
{
struct adv_softc *adv = device_get_softc(dev);
@@ -739,9 +719,9 @@
LIST_INIT(&adv->pending_ccbs);
SLIST_INIT(&adv->free_ccb_infos);
adv->dev = dev;
- adv->unit = device_get_unit(dev);
- adv->tag = tag;
- adv->bsh = bsh;
+ adv->res = res;
+ adv->reg_off = offset;
+ mtx_init(&adv->lock, "adv", NULL, MTX_DEF);
return(adv);
}
@@ -774,6 +754,7 @@
if (adv->ccb_infos != NULL)
free(adv->ccb_infos, M_DEVBUF);
case 0:
+ mtx_destroy(&adv->lock);
break;
}
}
@@ -787,6 +768,7 @@
u_int16_t config_lsw;
u_int16_t config_msw;
+ mtx_lock(&adv->lock);
adv_lib_init(adv);
/*
@@ -795,14 +777,16 @@
adv_write_lram_16(adv, ADV_HALTCODE_W, 0x00FE);
adv_stop_execution(adv);
if (adv_stop_chip(adv) == 0 || adv_is_chip_halted(adv) == 0) {
- printf("adv%d: Unable to halt adapter. Initialization"
- "failed\n", adv->unit);
+ mtx_unlock(&adv->lock);
+ device_printf(adv->dev,
+ "Unable to halt adapter. Initialization failed\n");
return (1);
}
ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
- printf("adv%d: Unable to set program counter. Initialization"
- "failed\n", adv->unit);
+ mtx_unlock(&adv->lock);
+ device_printf(adv->dev,
+ "Unable to set program counter. Initialization failed\n");
return (1);
}
@@ -877,8 +861,8 @@
} else {
u_int8_t sync_data;
- printf("adv%d: Warning EEPROM Checksum mismatch. "
- "Using default device parameters\n", adv->unit);
+ device_printf(adv->dev, "Warning EEPROM Checksum mismatch. "
+ "Using default device parameters\n");
/* Set reasonable defaults since we can't read the EEPROM */
adv->isa_dma_speed = /*ADV_DEF_ISA_DMA_SPEED*/1;
@@ -941,13 +925,15 @@
* to be 100% correct.
*/
if (adv_set_eeprom_config(adv, &eeprom_config) != 0)
- printf("%s: WARNING! Failure writing to EEPROM.\n",
- adv_name(adv));
+ device_printf(adv->dev,
+ "WARNING! Failure writing to EEPROM.\n");
#endif
adv_set_chip_scsiid(adv, adv->scsi_id);
- if (adv_init_lram_and_mcode(adv))
+ if (adv_init_lram_and_mcode(adv)) {
+ mtx_unlock(&adv->lock);
return (1);
+ }
adv->disc_enable = adv->user_disc_enable;
@@ -970,10 +956,12 @@
}
adv_write_lram_8(adv, ADVV_USE_TAGGED_QNG_B, TARGET_BIT_VECTOR_SET);
adv_write_lram_8(adv, ADVV_CAN_TAGGED_QNG_B, TARGET_BIT_VECTOR_SET);
- printf("adv%d: AdvanSys %s Host Adapter, SCSI ID %d, queue depth %d\n",
- adv->unit, (adv->type & ADV_ULTRA) && (max_sync == 0)
- ? "Ultra SCSI" : "SCSI",
- adv->scsi_id, adv->max_openings);
+ device_printf(adv->dev,
+ "AdvanSys %s Host Adapter, SCSI ID %d, queue depth %d\n",
+ (adv->type & ADV_ULTRA) && (max_sync == 0)
+ ? "Ultra SCSI" : "SCSI",
+ adv->scsi_id, adv->max_openings);
+ mtx_unlock(&adv->lock);
return (0);
}
@@ -981,6 +969,16 @@
adv_intr(void *arg)
{
struct adv_softc *adv;
+
+ adv = arg;
+ mtx_lock(&adv->lock);
+ adv_intr_locked(adv);
+ mtx_unlock(&adv->lock);
+}
+
+void
+adv_intr_locked(struct adv_softc *adv)
+{
u_int16_t chipstat;
u_int16_t saved_ram_addr;
u_int8_t ctrl_reg;
@@ -987,8 +985,8 @@
u_int8_t saved_ctrl_reg;
u_int8_t host_flag;
- adv = (struct adv_softc *)arg;
-
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
chipstat = ADV_INW(adv, ADV_CHIP_STATUS);
/* Is it for us? */
@@ -1001,7 +999,7 @@
ADV_CC_TEST));
if ((chipstat & (ADV_CSW_SCSI_RESET_LATCH|ADV_CSW_SCSI_RESET_ACTIVE))) {
- printf("Detected Bus Reset\n");
+ device_printf(adv->dev, "Detected Bus Reset\n");
adv_reset_bus(adv, /*initiate_reset*/FALSE);
return;
}
@@ -1129,9 +1127,11 @@
{
struct adv_ccb_info *cinfo;
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
cinfo = (struct adv_ccb_info *)ccb->ccb_h.ccb_cinfo_ptr;
LIST_REMOVE(&ccb->ccb_h, sim_links.le);
- untimeout(adv_timeout, ccb, ccb->ccb_h.timeout_ch);
+ callout_stop(&cinfo->timer);
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
bus_dmasync_op_t op;
@@ -1240,7 +1240,7 @@
case QHSTA_M_MICRO_CODE_ERROR_HALT:
default:
panic("%s: Unhandled Host status error %x",
- adv_name(adv), host_stat);
+ device_get_nameunit(adv->dev), host_stat);
/* NOTREACHED */
}
break;
@@ -1281,7 +1281,8 @@
static void
adv_poll(struct cam_sim *sim)
{
- adv_intr(cam_sim_softc(sim));
+
+ adv_intr_locked(cam_sim_softc(sim));
}
/*
@@ -1351,7 +1352,7 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &adv->lock,
&adv->buffer_dmat) != 0) {
return (ENXIO);
}
@@ -1372,7 +1373,7 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &adv->lock,
&adv->sense_dmat) != 0) {
return (ENXIO);
}
@@ -1399,8 +1400,8 @@
* Fire up the chip
*/
if (adv_start_chip(adv) != 1) {
- printf("adv%d: Unable to start on board processor. Aborting.\n",
- adv->unit);
+ device_printf(adv->dev,
+ "Unable to start on board processor. Aborting.\n");
return (ENXIO);
}
@@ -1414,8 +1415,8 @@
/*
* Construct our SIM entry.
*/
- adv->sim = cam_sim_alloc(adv_action, adv_poll, "adv", adv, adv->unit,
- &Giant, 1, adv->max_openings, devq);
+ adv->sim = cam_sim_alloc(adv_action, adv_poll, "adv", adv,
+ device_get_unit(adv->dev), &adv->lock, 1, adv->max_openings, devq);
if (adv->sim == NULL)
return (ENOMEM);
@@ -1424,8 +1425,10 @@
*
* XXX Twin Channel EISA Cards???
*/
+ mtx_lock(&adv->lock);
if (xpt_bus_register(adv->sim, adv->dev, 0) != CAM_SUCCESS) {
cam_sim_free(adv->sim, /*free devq*/TRUE);
+ mtx_unlock(&adv->lock);
return (ENXIO);
}
@@ -1434,6 +1437,7 @@
!= CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(adv->sim));
cam_sim_free(adv->sim, /*free devq*/TRUE);
+ mtx_unlock(&adv->lock);
return (ENXIO);
}
@@ -1443,6 +1447,7 @@
csa.callback = advasync;
csa.callback_arg = adv;
xpt_action((union ccb *)&csa);
+ mtx_unlock(&adv->lock);
return (0);
}
MODULE_DEPEND(adv, cam, 1, 1, 1);
Modified: trunk/sys/dev/advansys/advansys.h
===================================================================
--- trunk/sys/dev/advansys/advansys.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/advansys.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/advansys.h,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Generic driver definitions and exported functions for the Advanced
* Systems Inc. SCSI controllers
@@ -39,9 +39,7 @@
#include <dev/advansys/advlib.h>
-struct adv_softc * adv_alloc(device_t dev, bus_space_tag_t tag,
- bus_space_handle_t bsh);
-char * adv_name(struct adv_softc *adv);
+struct adv_softc * adv_alloc(device_t dev, struct resource *res, long offset);
void adv_map(void *arg, bus_dma_segment_t *segs,
int nseg, int error);
void adv_free(struct adv_softc *adv);
@@ -51,6 +49,6 @@
void adv_done(struct adv_softc *adv, union ccb* ccb,
u_int done_stat, u_int host_stat,
u_int scsi_stat, u_int q_no);
-timeout_t adv_timeout;
+void adv_timeout(void *arg);
#endif /* _ADVANSYS_H_ */
Modified: trunk/sys/dev/advansys/advlib.c
===================================================================
--- trunk/sys/dev/advansys/advlib.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/advlib.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/advlib.c,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Low level routines for the Advanced Systems Inc. SCSI controllers chips
*
@@ -46,7 +46,10 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
#include <sys/kernel.h>
+#include <sys/mutex.h>
#include <sys/systm.h>
#include <machine/bus.h>
@@ -299,6 +302,7 @@
struct adv_softc *adv;
adv = (struct adv_softc *)callback_arg;
+ mtx_assert(&adv->lock, MA_OWNED);
switch (code) {
case AC_FOUND_DEVICE:
{
@@ -461,12 +465,12 @@
* found, 0 otherwise.
*/
int
-adv_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh)
+adv_find_signature(struct resource *res)
{
u_int16_t signature;
- if (bus_space_read_1(tag, bsh, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
- signature = bus_space_read_2(tag, bsh, ADV_SIGNATURE_WORD);
+ if (bus_read_1(res, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
+ signature = bus_read_2(res, ADV_SIGNATURE_WORD);
if ((signature == ADV_1000_ID0W)
|| (signature == ADV_1000_ID0W_FIX))
return (1);
@@ -595,8 +599,8 @@
retval = adv_load_microcode(adv, 0, (u_int16_t *)adv_mcode,
adv_mcode_size);
if (retval != adv_mcode_chksum) {
- printf("adv%d: Microcode download failed checksum!\n",
- adv->unit);
+ device_printf(adv->dev,
+ "Microcode download failed checksum!\n");
return (1);
}
@@ -693,6 +697,8 @@
u_int8_t sg_entry_cnt_minus_one;
u_int8_t tid_no;
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
scsiq->q1.q_no = 0;
retval = 1; /* Default to error case */
target_ix = scsiq->q2.target_ix;
@@ -939,6 +945,8 @@
u_int8_t q_cntl;
u_int8_t tid_no;
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
int_halt_code = adv_read_lram_16(adv, ADVV_HALTCODE_W);
halt_qp = adv_read_lram_8(adv, ADVV_CURCDB_B);
halt_q_addr = ADV_QNO_TO_QADDR(halt_qp);
@@ -967,6 +975,7 @@
target_mask, tid_no);
} else if (int_halt_code == ADV_HALT_CHK_CONDITION) {
struct adv_target_transinfo* tinfo;
+ struct adv_ccb_info *cinfo;
union ccb *ccb;
u_int32_t cinfo_index;
u_int8_t tag_code;
@@ -1009,6 +1018,7 @@
*/
cinfo_index =
adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
+ cinfo = &adv->ccb_infos[cinfo_index];
ccb = adv->ccb_infos[cinfo_index].ccb;
xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
ccb->ccb_h.status |= CAM_DEV_QFRZN;
@@ -1022,9 +1032,7 @@
* Ensure we have enough time to actually
* retrieve the sense.
*/
- untimeout(adv_timeout, (caddr_t)ccb, ccb->ccb_h.timeout_ch);
- ccb->ccb_h.timeout_ch =
- timeout(adv_timeout, (caddr_t)ccb, 5 * hz);
+ callout_reset(&cinfo->timer, 5 * hz, adv_timeout, ccb);
} else if (int_halt_code == ADV_HALT_SDTR_REJECTED) {
struct ext_msg out_msg;
@@ -1091,6 +1099,7 @@
u_int old_offset;
u_int8_t sdtr_data;
+ mtx_assert(&adv->lock, MA_OWNED);
tinfo = &adv->tinfo[tid];
/* Filter our input */
@@ -1103,10 +1112,8 @@
if ((type & ADV_TRANS_CUR) != 0
&& ((old_period != period || old_offset != offset)
|| period == 0 || offset == 0) /*Changes in asyn fix settings*/) {
- int s;
int halted;
- s = splcam();
halted = adv_is_chip_halted(adv);
if (halted == 0)
/* Must halt the chip first */
@@ -1126,7 +1133,6 @@
/* Start the chip again */
adv_start_chip(adv);
- splx(s);
tinfo->current.period = period;
tinfo->current.offset = offset;
@@ -1236,8 +1242,8 @@
u_int16_t set_value, int count)
{
ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
- bus_space_set_multi_2(adv->tag, adv->bsh, ADV_LRAM_DATA,
- set_value, count);
+ bus_set_multi_2(adv->res, adv->reg_off + ADV_LRAM_DATA,
+ set_value, count);
}
static u_int32_t
@@ -1508,8 +1514,8 @@
ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
- printf("adv%d: Unable to set program counter. Aborting.\n",
- adv->unit);
+ device_printf(adv->dev,
+ "Unable to set program counter. Aborting.\n");
return (1);
}
return (0);
@@ -2003,6 +2009,8 @@
u_int8_t target_ix;
int count;
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
scsiq = &scsiq_buf;
target_ix = ADV_TIDLUN_TO_IX(target, lun);
count = 0;
@@ -2046,6 +2054,8 @@
int i;
union ccb *ccb;
+ if (!dumping)
+ mtx_assert(&adv->lock, MA_OWNED);
i = 200;
while ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_SCSI_RESET_ACTIVE) != 0
&& i--)
Modified: trunk/sys/dev/advansys/advlib.h
===================================================================
--- trunk/sys/dev/advansys/advlib.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/advlib.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/advlib.h,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Definitions for low level routines and data structures
* for the Advanced Systems Inc. SCSI controllers chips.
@@ -95,6 +95,7 @@
struct adv_ccb_info {
adv_ccb_state state;
bus_dmamap_t dmamap;
+ struct callout timer;
union ccb* ccb;
SLIST_ENTRY(adv_ccb_info) links;
};
@@ -497,8 +498,8 @@
struct adv_softc {
device_t dev;
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
+ struct resource *res;
+ long reg_off;
struct cam_sim *sim;
LIST_HEAD(, ccb_hdr) pending_ccbs;
struct adv_ccb_info *ccb_infos;
@@ -540,8 +541,7 @@
adv_state state;
struct cam_path *path;
- int unit;
- int init_level;
+ int init_level;
u_int32_t max_dma_addr;
u_int32_t max_dma_count;
u_int8_t isa_dma_speed;
@@ -555,6 +555,7 @@
u_int8_t ccb_infos_allocated;
u_int8_t *sdtr_period_tbl;
u_int8_t sdtr_period_tbl_size;
+ struct mtx lock;
};
/*
@@ -794,7 +795,7 @@
u_int16_t value);
/* Intialization */
-int adv_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh);
+int adv_find_signature(struct resource *res);
void adv_lib_init(struct adv_softc *adv);
u_int16_t adv_get_eeprom_config(struct adv_softc *adv,
@@ -847,11 +848,11 @@
struct cam_path *path, void *arg);
#define ADV_INB(adv, offset) \
- bus_space_read_1((adv)->tag, (adv)->bsh, offset)
+ bus_read_1((adv)->res, (adv)->reg_off + offset)
#define ADV_INW(adv, offset) \
- bus_space_read_2((adv)->tag, (adv)->bsh, offset)
+ bus_read_2((adv)->res, (adv)->reg_off + offset)
#define ADV_INSB(adv, offset, valp, count) \
- bus_space_read_multi_1((adv)->tag, (adv)->bsh, offset, valp, count)
+ bus_read_multi_1((adv)->res, (adv)->reg_off + offset, valp, count)
/* These controllers seem to have problems with PIO on some fast processors */
static __inline void ADV_INSW(struct adv_softc *, u_int, u_int16_t *, u_int);
@@ -859,13 +860,13 @@
ADV_INSW(struct adv_softc *adv, u_int offset, u_int16_t *valp, u_int count)
{
while (count--)
- *valp++ = bus_space_read_2(adv->tag, adv->bsh, offset);
+ *valp++ = bus_read_2(adv->res, adv->reg_off + offset);
}
#define ADV_OUTB(adv, offset, val) \
- bus_space_write_1((adv)->tag, (adv)->bsh, offset, val)
+ bus_write_1((adv)->res, (adv)->reg_off + offset, val)
#define ADV_OUTW(adv, offset, val) \
- bus_space_write_2((adv)->tag, (adv)->bsh, offset, val)
+ bus_write_2((adv)->res, (adv)->reg_off + offset, val)
/* These controllers seem to have problems with PIO on some fast processors */
static __inline void ADV_OUTSW(struct adv_softc *, u_int, u_int16_t *, u_int);
@@ -873,7 +874,7 @@
ADV_OUTSW(struct adv_softc *adv, u_int offset, u_int16_t *valp, u_int count)
{
while (count--)
- bus_space_write_2(adv->tag, adv->bsh, offset, *valp++);
+ bus_write_2(adv->res, adv->reg_off + offset, *valp++);
}
#endif /* _ADVLIB_H_ */
Modified: trunk/sys/dev/advansys/adw_pci.c
===================================================================
--- trunk/sys/dev/advansys/adw_pci.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adw_pci.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adw_pci.c,v 1.2 2008/12/02 02:24:29 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Device probe and attach routines for the following
* Advanced Systems Inc. SCSI controllers:
@@ -255,8 +255,7 @@
return (error);
/* Ensure busmastering is enabled */
- command |= PCIM_CMD_BUSMASTEREN;
- pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
+ pci_enable_busmaster(dev);
/* Allocate a dmatag for our transfer DMA maps */
error = bus_dma_tag_create(
@@ -271,15 +270,15 @@
/* nsegments */ ~0,
/* maxsegsz */ ADW_PCI_MAX_DMA_COUNT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adw->parent_dmat);
adw->init_level++;
if (error != 0) {
- printf("%s: Could not allocate DMA tag - error %d\n",
- adw_name(adw), error);
+ device_printf(dev, "Could not allocate DMA tag - error %d\n",
+ error);
adw_free(adw);
return (error);
}
Modified: trunk/sys/dev/advansys/adwcam.c
===================================================================
--- trunk/sys/dev/advansys/adwcam.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adwcam.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adwcam.c,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* CAM SCSI interface for the Advanced Systems Inc.
* Second Generation SCSI controllers.
@@ -48,6 +48,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -75,8 +76,6 @@
#define ccb_acb_ptr spriv_ptr0
#define ccb_adw_ptr spriv_ptr1
-u_long adw_unit;
-
static __inline cam_status adwccbstatus(union ccb*);
static __inline struct acb* adwgetacb(struct adw_softc *adw);
static __inline void adwfreeacb(struct adw_softc *adw,
@@ -91,6 +90,7 @@
static void adwexecuteacb(void *arg, bus_dma_segment_t *dm_segs,
int nseg, int error);
static void adw_action(struct cam_sim *sim, union ccb *ccb);
+static void adw_intr_locked(struct adw_softc *adw);
static void adw_poll(struct cam_sim *sim);
static void adw_async(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg);
@@ -111,9 +111,9 @@
adwgetacb(struct adw_softc *adw)
{
struct acb* acb;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&adw->lock, MA_OWNED);
if ((acb = SLIST_FIRST(&adw->free_acb_list)) != NULL) {
SLIST_REMOVE_HEAD(&adw->free_acb_list, links);
} else if (adw->num_acbs < adw->max_acbs) {
@@ -120,12 +120,11 @@
adwallocacbs(adw);
acb = SLIST_FIRST(&adw->free_acb_list);
if (acb == NULL)
- printf("%s: Can't malloc ACB\n", adw_name(adw));
+ device_printf(adw->device, "Can't malloc ACB\n");
else {
SLIST_REMOVE_HEAD(&adw->free_acb_list, links);
}
}
- splx(s);
return (acb);
}
@@ -133,9 +132,9 @@
static __inline void
adwfreeacb(struct adw_softc *adw, struct acb *acb)
{
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&adw->lock, MA_OWNED);
if ((acb->state & ACB_ACTIVE) != 0)
LIST_REMOVE(&acb->ccb->ccb_h, sim_links.le);
if ((acb->state & ACB_RELEASE_SIMQ) != 0)
@@ -147,7 +146,6 @@
}
acb->state = ACB_FREE;
SLIST_INSERT_HEAD(&adw->free_acb_list, acb, links);
- splx(s);
}
static void
@@ -187,7 +185,6 @@
/*
* Allocate another chunk of CCB's. Return count of entries added.
- * Assumed to be called at splcam().
*/
static int
adwallocacbs(struct adw_softc *adw)
@@ -223,6 +220,7 @@
next_acb->sg_blocks = blocks;
next_acb->sg_busaddr = busaddr;
next_acb->state = ACB_FREE;
+ callout_init_mtx(&next_acb->timer, &adw->lock, 0);
SLIST_INSERT_HEAD(&adw->free_acb_list, next_acb, links);
blocks += ADW_SG_BLOCKCNT;
busaddr += ADW_SG_BLOCKCNT * sizeof(*blocks);
@@ -238,16 +236,17 @@
struct acb *acb;
union ccb *ccb;
struct adw_softc *adw;
- int s;
acb = (struct acb *)arg;
ccb = acb->ccb;
adw = (struct adw_softc *)ccb->ccb_h.ccb_adw_ptr;
+ if (!dumping)
+ mtx_assert(&adw->lock, MA_OWNED);
if (error != 0) {
if (error != EFBIG)
- printf("%s: Unexepected error 0x%x returned from "
- "bus_dmamap_load\n", adw_name(adw), error);
+ device_printf(adw->device, "Unexepected error 0x%x "
+ "returned from bus_dmamap_load\n", error);
if (ccb->ccb_h.status == CAM_REQ_INPROG) {
xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
@@ -316,8 +315,6 @@
acb->queue.sg_real_addr = 0;
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -327,7 +324,6 @@
bus_dmamap_unload(adw->buffer_dmat, acb->dmamap);
adwfreeacb(adw, acb);
xpt_done(ccb);
- splx(s);
return;
}
@@ -334,13 +330,10 @@
acb->state |= ACB_ACTIVE;
ccb->ccb_h.status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&adw->pending_ccbs, &ccb->ccb_h, sim_links.le);
- ccb->ccb_h.timeout_ch =
- timeout(adwtimeout, (caddr_t)acb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&acb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+ adwtimeout, acb);
adw_send_acb(adw, acb, acbvtob(adw, acb));
-
- splx(s);
}
static void
@@ -351,6 +344,8 @@
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("adw_action\n"));
adw = (struct adw_softc *)cam_sim_softc(sim);
+ if (!dumping)
+ mtx_assert(&adw->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
/* Common cases first */
@@ -371,11 +366,7 @@
}
if ((acb = adwgetacb(adw)) == NULL) {
- int s;
-
- s = splcam();
adw->state |= ADW_RESOURCE_SHORTAGE;
- splx(s);
xpt_freeze_simq(sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@@ -448,10 +439,8 @@
* to a single buffer.
*/
if ((ccbh->flags & CAM_DATA_PHYS) == 0) {
- int s;
int error;
- s = splsoftvm();
error =
bus_dmamap_load(adw->buffer_dmat,
acb->dmamap,
@@ -469,7 +458,6 @@
xpt_freeze_simq(sim, 1);
acb->state |= CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -531,12 +519,10 @@
struct ccb_trans_settings_spi *spi;
struct ccb_trans_settings *cts;
u_int target_mask;
- int s;
cts = &ccb->cts;
target_mask = 0x01 << ccb->ccb_h.target_id;
- s = splcam();
scsi = &cts->proto_specific.scsi;
spi = &cts->xport_specific.spi;
if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
@@ -648,7 +634,6 @@
}
}
}
- splx(s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@@ -802,7 +787,7 @@
static void
adw_poll(struct cam_sim *sim)
{
- adw_intr(cam_sim_softc(sim));
+ adw_intr_locked(cam_sim_softc(sim));
}
static void
@@ -814,33 +799,15 @@
adw_alloc(device_t dev, struct resource *regs, int regs_type, int regs_id)
{
struct adw_softc *adw;
- int i;
-
- /*
- * Allocate a storage area for us
- */
- adw = malloc(sizeof(struct adw_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (adw == NULL) {
- printf("adw%d: cannot malloc!\n", device_get_unit(dev));
- return NULL;
- }
+
+ adw = device_get_softc(dev);
LIST_INIT(&adw->pending_ccbs);
SLIST_INIT(&adw->sg_maps);
+ mtx_init(&adw->lock, "adw", NULL, MTX_DEF);
adw->device = dev;
- adw->unit = device_get_unit(dev);
adw->regs_res_type = regs_type;
adw->regs_res_id = regs_id;
adw->regs = regs;
- adw->tag = rman_get_bustag(regs);
- adw->bsh = rman_get_bushandle(regs);
- i = adw->unit / 10;
- adw->name = malloc(sizeof("adw") + i + 1, M_DEVBUF, M_NOWAIT);
- if (adw->name == NULL) {
- printf("adw%d: cannot malloc name!\n", adw->unit);
- free(adw, M_DEVBUF);
- return NULL;
- }
- sprintf(adw->name, "adw%d", adw->unit);
return(adw);
}
@@ -905,8 +872,7 @@
xpt_bus_deregister(cam_sim_path(adw->sim));
cam_sim_free(adw->sim, /*free_devq*/TRUE);
}
- free(adw->name, M_DEVBUF);
- free(adw, M_DEVBUF);
+ mtx_destroy(&adw->lock);
}
int
@@ -925,8 +891,8 @@
u_int16_t serial_number[3];
adw->flags |= ADW_EEPROM_FAILED;
- printf("%s: EEPROM checksum failed. Restoring Defaults\n",
- adw_name(adw));
+ device_printf(adw->device,
+ "EEPROM checksum failed. Restoring Defaults\n");
/*
* Restore the default EEPROM settings.
@@ -1005,10 +971,10 @@
if ((adw->features & ADW_ULTRA2) != 0) {
switch (eep_config.termination_lvd) {
default:
- printf("%s: Invalid EEPROM LVD Termination Settings.\n",
- adw_name(adw));
- printf("%s: Reverting to Automatic LVD Termination\n",
- adw_name(adw));
+ device_printf(adw->device,
+ "Invalid EEPROM LVD Termination Settings.\n");
+ device_printf(adw->device,
+ "Reverting to Automatic LVD Termination\n");
/* FALLTHROUGH */
case ADW_EEPROM_TERM_AUTO:
break;
@@ -1026,10 +992,10 @@
switch (eep_config.termination_se) {
default:
- printf("%s: Invalid SE EEPROM Termination Settings.\n",
- adw_name(adw));
- printf("%s: Reverting to Automatic SE Termination\n",
- adw_name(adw));
+ device_printf(adw->device,
+ "Invalid SE EEPROM Termination Settings.\n");
+ device_printf(adw->device,
+ "Reverting to Automatic SE Termination\n");
/* FALLTHROUGH */
case ADW_EEPROM_TERM_AUTO:
break;
@@ -1043,7 +1009,7 @@
scsicfg1 |= ADW_SCSI_CFG1_TERM_CTL_MANUAL;
break;
}
- printf("%s: SCSI ID %d, ", adw_name(adw), adw->initiator_id);
+ device_printf(adw->device, "SCSI ID %d, ", adw->initiator_id);
/* DMA tag for mapping buffers into device visible space. */
if (bus_dma_tag_create(
@@ -1059,7 +1025,7 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &adw->lock,
&adw->buffer_dmat) != 0) {
return (ENOMEM);
}
@@ -1081,8 +1047,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adw->carrier_dmat) != 0) {
return (ENOMEM);
}
@@ -1142,8 +1108,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adw->acb_dmat) != 0) {
return (ENOMEM);
}
@@ -1179,8 +1145,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&adw->sg_dmat) != 0) {
return (ENOMEM);
}
@@ -1188,13 +1154,19 @@
adw->init_level++;
/* Allocate our first batch of ccbs */
- if (adwallocacbs(adw) == 0)
+ mtx_lock(&adw->lock);
+ if (adwallocacbs(adw) == 0) {
+ mtx_unlock(&adw->lock);
return (ENOMEM);
+ }
- if (adw_init_chip(adw, scsicfg1) != 0)
+ if (adw_init_chip(adw, scsicfg1) != 0) {
+ mtx_unlock(&adw->lock);
return (ENXIO);
+ }
printf("Queue Depth %d\n", adw->max_acbs);
+ mtx_unlock(&adw->lock);
return (0);
}
@@ -1207,18 +1179,16 @@
{
struct ccb_setasync csa;
struct cam_devq *devq;
- int s;
int error;
- error = 0;
- s = splcam();
/* Hook up our interrupt handler */
- if ((error = bus_setup_intr(adw->device, adw->irq,
- INTR_TYPE_CAM | INTR_ENTROPY, NULL,
- adw_intr, adw, &adw->ih)) != 0) {
+ error = bus_setup_intr(adw->device, adw->irq,
+ INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE, NULL, adw_intr, adw,
+ &adw->ih);
+ if (error != 0) {
device_printf(adw->device, "bus_setup_intr() failed: %d\n",
error);
- goto fail;
+ return (error);
}
/* Start the Risc processor now that we are fully configured. */
@@ -1234,16 +1204,15 @@
/*
* Construct our SIM entry.
*/
- adw->sim = cam_sim_alloc(adw_action, adw_poll, "adw", adw, adw->unit,
- &Giant, 1, adw->max_acbs, devq);
- if (adw->sim == NULL) {
- error = ENOMEM;
- goto fail;
- }
+ adw->sim = cam_sim_alloc(adw_action, adw_poll, "adw", adw,
+ device_get_unit(adw->device), &adw->lock, 1, adw->max_acbs, devq);
+ if (adw->sim == NULL)
+ return (ENOMEM);
/*
* Register the bus.
*/
+ mtx_lock(&adw->lock);
if (xpt_bus_register(adw->sim, adw->device, 0) != CAM_SUCCESS) {
cam_sim_free(adw->sim, /*free devq*/TRUE);
error = ENOMEM;
@@ -1262,7 +1231,7 @@
}
fail:
- splx(s);
+ mtx_unlock(&adw->lock);
return (error);
}
@@ -1270,9 +1239,18 @@
adw_intr(void *arg)
{
struct adw_softc *adw;
+
+ adw = arg;
+ mtx_lock(&adw->lock);
+ adw_intr_locked(adw);
+ mtx_unlock(&adw->lock);
+}
+
+void
+adw_intr_locked(struct adw_softc *adw)
+{
u_int int_stat;
- adw = (struct adw_softc *)arg;
if ((adw_inw(adw, ADW_CTRL_REG) & ADW_CTRL_REG_HOST_INTR) == 0)
return;
@@ -1297,7 +1275,7 @@
/*
* The firmware detected a SCSI Bus reset.
*/
- printf("Someone Reset the Bus\n");
+ device_printf(adw->device, "Someone Reset the Bus\n");
adw_handle_bus_reset(adw, /*initiated*/FALSE);
break;
case ADW_ASYNC_RDMA_FAILURE:
@@ -1357,7 +1335,7 @@
/* Process CCB */
ccb = acb->ccb;
- untimeout(adwtimeout, acb, ccb->ccb_h.timeout_ch);
+ callout_stop(&acb->timer);
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
bus_dmasync_op_t op;
@@ -1434,6 +1412,7 @@
break;
case QHSTA_M_QUEUE_ABORTED:
/* BDR or Bus Reset */
+ xpt_print_path(adw->path);
printf("Saw Queue Aborted\n");
ccb->ccb_h.status = adw->last_reset;
break;
@@ -1447,7 +1426,7 @@
{
/* The SCSI bus hung in a phase */
xpt_print_path(adw->path);
- printf("Watch Dog timer expired. Reseting bus\n");
+ printf("Watch Dog timer expired. Resetting bus\n");
adw_reset_bus(adw);
break;
}
@@ -1476,7 +1455,8 @@
break;
default:
panic("%s: Unhandled Host status error %x",
- adw_name(adw), acb->queue.host_status);
+ device_get_nameunit(adw->device),
+ acb->queue.host_status);
/* NOTREACHED */
}
}
@@ -1501,7 +1481,6 @@
struct adw_softc *adw;
adw_idle_cmd_status_t status;
int target_id;
- int s;
acb = (struct acb *)arg;
ccb = acb->ccb;
@@ -1509,13 +1488,12 @@
xpt_print_path(ccb->ccb_h.path);
printf("ACB %p - timed out\n", (void *)acb);
- s = splcam();
+ mtx_assert(&adw->lock, MA_OWNED);
if ((acb->state & ACB_ACTIVE) == 0) {
xpt_print_path(ccb->ccb_h.path);
printf("ACB %p - timed out CCB already completed\n",
(void *)acb);
- splx(s);
return;
}
@@ -1525,10 +1503,9 @@
/* Attempt a BDR first */
status = adw_idle_cmd_send(adw, ADW_IDLE_CMD_DEVICE_RESET,
ccb->ccb_h.target_id);
- splx(s);
if (status == ADW_IDLE_CMD_SUCCESS) {
- printf("%s: BDR Delivered. No longer in timeout\n",
- adw_name(adw));
+ device_printf(adw->device,
+ "BDR Delivered. No longer in timeout\n");
adw_handle_device_reset(adw, target_id);
} else {
adw_reset_bus(adw);
Modified: trunk/sys/dev/advansys/adwlib.c
===================================================================
--- trunk/sys/dev/advansys/adwlib.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adwlib.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adwlib.c,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Low level routines for Second Generation
* Advanced Systems Inc. SCSI controllers chips
@@ -47,8 +47,12 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/rman.h>
#include <machine/bus.h>
@@ -199,6 +203,8 @@
{
adw_idle_cmd_status_t status;
+ if (!dumping)
+ mtx_assert(&adw->lock, MA_OWNED);
status =
adw_idle_cmd_send(adw, ADW_IDLE_CMD_SCSI_RESET_START, /*param*/0);
if (status != ADW_IDLE_CMD_SUCCESS) {
@@ -250,7 +256,8 @@
DELAY(1000);
}
if (i == ADW_EEP_DELAY_MS)
- panic("%s: Timedout Reading EEPROM", adw_name(adw));
+ panic("%s: Timedout Reading EEPROM",
+ device_get_nameunit(adw->device));
}
/*
@@ -474,7 +481,7 @@
checksum += adw_inw(adw, ADW_RAM_DATA);
if (checksum != adw->mcode_data->mcode_chksum) {
- printf("%s: Firmware load failed!\n", adw_name(adw));
+ device_printf(adw->device, "Firmware load failed!\n");
return (EIO);
}
@@ -551,8 +558,8 @@
* this condition is found.
*/
if ((adw_inw(adw, ADW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
- printf("%s: Illegal Cable Config!\n", adw_name(adw));
- printf("%s: Internal cable is reversed!\n", adw_name(adw));
+ device_printf(adw->device, "Illegal Cable Config!\n");
+ device_printf(adw->device, "Internal cable is reversed!\n");
return (EIO);
}
@@ -563,17 +570,17 @@
if ((adw->features & ADW_ULTRA) != 0) {
if ((scsicfg1 & ADW_SCSI_CFG1_DIFF_MODE) != 0
&& (scsicfg1 & ADW_SCSI_CFG1_DIFF_SENSE) == 0) {
- printf("%s: A Single Ended Device is attached to our "
- "differential bus!\n", adw_name(adw));
+ device_printf(adw->device, "A Single Ended Device is "
+ "attached to our differential bus!\n");
return (EIO);
}
} else {
if ((scsicfg1 & ADW2_SCSI_CFG1_DEV_DETECT_HVD) != 0) {
- printf("%s: A High Voltage Differential Device "
- "is attached to this controller.\n",
- adw_name(adw));
- printf("%s: HVD devices are not supported.\n",
- adw_name(adw));
+ device_printf(adw->device,
+ "A High Voltage Differential Device "
+ "is attached to this controller.\n");
+ device_printf(adw->device,
+ "HVD devices are not supported.\n");
return (EIO);
}
}
@@ -648,10 +655,10 @@
cable_count++;
if (cable_count == 3) {
- printf("%s: Illegal Cable Config!\n",
- adw_name(adw));
- printf("%s: Only Two Ports may be used at "
- "a time!\n", adw_name(adw));
+ device_printf(adw->device,
+ "Illegal Cable Config!\n");
+ device_printf(adw->device,
+ "Only Two Ports may be used at a time!\n");
} else if (cable_count <= 1) {
/*
* At least two out of three cables missing.
@@ -853,9 +860,9 @@
{
u_int timeout;
adw_idle_cmd_status_t status;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&adw->lock, MA_OWNED);
/*
* Clear the idle command status which is set by the microcode
@@ -887,7 +894,7 @@
}
if (timeout == 0)
- panic("%s: Idle Command Timed Out!\n", adw_name(adw));
- splx(s);
+ panic("%s: Idle Command Timed Out!",
+ device_get_nameunit(adw->device));
return (status);
}
Modified: trunk/sys/dev/advansys/adwlib.h
===================================================================
--- trunk/sys/dev/advansys/adwlib.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adwlib.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adwlib.h,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Definitions for low level routines and data structures
* for the Advanced Systems Inc. SCSI controllers chips.
@@ -422,6 +422,7 @@
acb_state state;
union ccb *ccb;
struct adw_sg_block* sg_blocks;
+ struct callout timer;
bus_addr_t sg_busaddr;
struct scsi_sense_data sense_data;
SLIST_ENTRY(acb) links;
@@ -602,8 +603,7 @@
#define ADW_NUM_CARRIER_QUEUES 2
struct adw_softc
{
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
+ struct resource *res;
adw_state state;
bus_dma_tag_t buffer_dmat;
struct acb *acbs;
@@ -627,6 +627,7 @@
adw_flag flags;
u_int memsize;
char channel;
+ struct mtx lock;
struct cam_path *path;
struct cam_sim *sim;
struct resource *regs;
@@ -642,8 +643,6 @@
u_int num_acbs;
u_int initiator_id;
u_int init_level;
- u_int unit;
- char* name;
cam_status last_reset; /* Last reset type */
u_int16_t bios_ctrl;
u_int16_t user_wdtr;
@@ -660,23 +659,22 @@
extern const int adw_num_syncrates;
#define adw_inb(adw, port) \
- bus_space_read_1((adw)->tag, (adw)->bsh, port)
+ bus_read_1((adw)->res, port)
#define adw_inw(adw, port) \
- bus_space_read_2((adw)->tag, (adw)->bsh, port)
+ bus_read_2((adw)->res, port)
#define adw_inl(adw, port) \
- bus_space_read_4((adw)->tag, (adw)->bsh, port)
+ bus_read_4((adw)->res, port)
#define adw_outb(adw, port, value) \
- bus_space_write_1((adw)->tag, (adw)->bsh, port, value)
+ bus_write_1((adw)->res, port, value)
#define adw_outw(adw, port, value) \
- bus_space_write_2((adw)->tag, (adw)->bsh, port, value)
+ bus_write_2((adw)->res, port, value)
#define adw_outl(adw, port, value) \
- bus_space_write_4((adw)->tag, (adw)->bsh, port, value)
+ bus_write_4((adw)->res, port, value)
#define adw_set_multi_2(adw, port, value, count) \
- bus_space_set_multi_2((adw)->tag, (adw)->bsh, port, value, count)
+ bus_set_multi_2((adw)->res, port, value, count)
-static __inline const char* adw_name(struct adw_softc *adw);
static __inline u_int adw_lram_read_8(struct adw_softc *adw, u_int addr);
static __inline u_int adw_lram_read_16(struct adw_softc *adw, u_int addr);
static __inline u_int adw_lram_read_32(struct adw_softc *adw, u_int addr);
@@ -706,12 +704,6 @@
carrierbtov(struct adw_softc *adw,
u_int32_t baddr);
-static __inline const char*
-adw_name(struct adw_softc *adw)
-{
- return (adw->name);
-}
-
static __inline u_int
adw_lram_read_8(struct adw_softc *adw, u_int addr)
{
Modified: trunk/sys/dev/advansys/adwvar.h
===================================================================
--- trunk/sys/dev/advansys/adwvar.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/advansys/adwvar.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/advansys/adwvar.h,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Generic driver definitions and exported functions for the Advanced
* Systems Inc. Second Generation SCSI controllers
@@ -50,7 +50,6 @@
void adw_done(struct adw_softc *adw, union ccb* ccb,
u_int done_stat, u_int host_stat,
u_int scsi_stat, u_int q_no);
-timeout_t adw_timeout;
+void adw_timeout(void *arg);
-extern u_long adw_unit;
#endif /* _ADWVAR_H_ */
Modified: trunk/sys/dev/aha/aha.c
===================================================================
--- trunk/sys/dev/aha/aha.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/aha/aha.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/aha/aha.c,v 1.3 2009/01/18 19:29:04 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*
* Generic register and struct definitions for the Adaptech 154x/164x
* SCSI host adapters. Product specific probe and attach routines can
@@ -62,6 +62,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -69,6 +70,7 @@
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/rman.h>
#include <machine/bus.h>
@@ -148,6 +150,7 @@
static bus_dmamap_callback_t ahaexecuteccb;
static void ahadone(struct aha_softc *aha, struct aha_ccb *accb,
aha_mbi_comp_code_t comp_code);
+static void aha_intr_locked(struct aha_softc *aha);
/* Host adapter command functions */
static int ahareset(struct aha_softc* aha, int hard_reset);
@@ -169,22 +172,19 @@
static void ahapoll(struct cam_sim *sim);
/* Our timeout handler */
-static timeout_t ahatimeout;
+static void ahatimeout(void *arg);
/* Exported functions */
void
-aha_alloc(struct aha_softc *aha, int unit, bus_space_tag_t tag,
- bus_space_handle_t bsh)
+aha_alloc(struct aha_softc *aha)
{
SLIST_INIT(&aha->free_aha_ccbs);
LIST_INIT(&aha->pending_ccbs);
SLIST_INIT(&aha->sg_maps);
- aha->unit = unit;
- aha->tag = tag;
- aha->bsh = bsh;
aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID;
aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID;
+ mtx_init(&aha->lock, "aha", NULL, MTX_DEF);
}
void
@@ -226,6 +226,7 @@
case 0:
break;
}
+ mtx_destroy(&aha->lock);
}
/*
@@ -465,7 +466,7 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &aha->lock,
&aha->buffer_dmat) != 0) {
goto error_exit;
}
@@ -485,8 +486,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->mailbox_dmat) != 0) {
goto error_exit;
}
@@ -524,8 +525,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->ccb_dmat) != 0) {
goto error_exit;
}
@@ -557,8 +558,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->sg_dmat) != 0)
goto error_exit;
@@ -606,14 +607,17 @@
/*
* Construct our SIM entry
*/
- aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, aha->unit,
- &Giant, 2, tagged_dev_openings, devq);
+ aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha,
+ device_get_unit(aha->dev), &aha->lock, 2, tagged_dev_openings,
+ devq);
if (aha->sim == NULL) {
cam_simq_free(devq);
return (ENOMEM);
}
+ mtx_lock(&aha->lock);
if (xpt_bus_register(aha->sim, aha->dev, 0) != CAM_SUCCESS) {
cam_sim_free(aha->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aha->lock);
return (ENXIO);
}
if (xpt_create_path(&aha->path, /*periph*/NULL, cam_sim_path(aha->sim),
@@ -620,8 +624,10 @@
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(aha->sim));
cam_sim_free(aha->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aha->lock);
return (ENXIO);
}
+ mtx_unlock(&aha->lock);
return (0);
}
@@ -665,6 +671,7 @@
next_ccb->sg_list = segs;
next_ccb->sg_list_phys = physaddr;
next_ccb->flags = ACCB_FREE;
+ callout_init_mtx(&next_ccb->timer, &aha->lock, 0);
error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0,
&next_ccb->dmamap);
if (error != 0)
@@ -686,9 +693,9 @@
static __inline void
ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb)
{
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&aha->lock, MA_OWNED);
if ((accb->flags & ACCB_ACTIVE) != 0)
LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le);
if (aha->resource_shortage != 0
@@ -699,7 +706,6 @@
accb->flags = ACCB_FREE;
SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links);
aha->active_ccbs--;
- splx(s);
}
static struct aha_ccb*
@@ -706,9 +712,9 @@
ahagetccb(struct aha_softc *aha)
{
struct aha_ccb* accb;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&aha->lock, MA_OWNED);
if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) {
SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links);
aha->active_ccbs++;
@@ -722,7 +728,6 @@
aha->active_ccbs++;
}
}
- splx(s);
return (accb);
}
@@ -731,11 +736,11 @@
ahaaction(struct cam_sim *sim, union ccb *ccb)
{
struct aha_softc *aha;
- int s;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n"));
aha = (struct aha_softc *)cam_sim_softc(sim);
+ mtx_assert(&aha->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
/* Common cases first */
@@ -748,9 +753,7 @@
* Get an accb to use.
*/
if ((accb = ahagetccb(aha)) == NULL) {
- s = splcam();
aha->resource_shortage = TRUE;
- splx(s);
xpt_freeze_simq(aha->sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@@ -819,7 +822,6 @@
if ((ccbh->flags & CAM_DATA_PHYS)==0) {
int error;
- s = splsoftvm();
error = bus_dmamap_load(
aha->buffer_dmat,
accb->dmamap,
@@ -841,7 +843,6 @@
csio->ccb_h.status |=
CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -1018,7 +1019,6 @@
struct aha_ccb *accb;
union ccb *ccb;
struct aha_softc *aha;
- int s;
uint32_t paddr;
accb = (struct aha_ccb *)arg;
@@ -1078,8 +1078,6 @@
ahautoa24(0, accb->hccb.data_addr);
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -1089,7 +1087,6 @@
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
ahafreeccb(aha, accb);
xpt_done(ccb);
- splx(s);
return;
}
@@ -1097,8 +1094,8 @@
ccb->ccb_h.status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le);
- ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&accb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+ ahatimeout, accb);
/* Tell the adapter about this command */
if (aha->cur_outbox->action_code != AMBO_FREE) {
@@ -1112,7 +1109,7 @@
device_printf(aha->dev,
"Encountered busy mailbox with %d out of %d "
"commands active!!!", aha->active_ccbs, aha->max_ccbs);
- untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch);
+ callout_stop(&accb->timer);
if (nseg != 0)
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
ahafreeccb(aha, accb);
@@ -1128,7 +1125,6 @@
aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
ahanextoutbox(aha);
- splx(s);
}
void
@@ -1135,10 +1131,19 @@
aha_intr(void *arg)
{
struct aha_softc *aha;
+
+ aha = arg;
+ mtx_lock(&aha->lock);
+ aha_intr_locked(aha);
+ mtx_unlock(&aha->lock);
+}
+
+void
+aha_intr_locked(struct aha_softc *aha)
+{
u_int intstat;
uint32_t paddr;
- aha = (struct aha_softc *)arg;
while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) {
if ((intstat & CMD_COMPLETE) != 0) {
aha->latched_status = aha_inb(aha, STATUS_REG);
@@ -1221,9 +1226,9 @@
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
ahadone(aha, pending_accb, AMBI_ERROR);
} else {
- ccb_h->timeout_ch = timeout(ahatimeout,
- (caddr_t)pending_accb,
- (ccb_h->timeout * hz) / 1000);
+ callout_reset(&pending_accb->timer,
+ (ccb_h->timeout * hz) / 1000,
+ ahatimeout, pending_accb);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
@@ -1231,7 +1236,7 @@
return;
}
- untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch);
+ callout_stop(&accb->timer);
switch (comp_code) {
case AMBI_FREE:
@@ -1447,7 +1452,6 @@
u_int saved_status;
u_int intstat;
u_int reply_buf_size;
- int s;
int cmd_complete;
int error;
@@ -1466,15 +1470,11 @@
* and wait for all completions to occur if necessary.
*/
timeout = 10000;
- s = splcam();
while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) {
/* Fire the interrupt handler in case interrupts are blocked */
aha_intr(aha);
- splx(s);
DELAY(10);
- s = splcam();
}
- splx(s);
if (timeout == 0) {
device_printf(aha->dev,
@@ -1517,10 +1517,8 @@
timeout = 10000;
while (param_len && --timeout) {
DELAY(100);
- s = splcam();
status = aha_inb(aha, STATUS_REG);
intstat = aha_inb(aha, INTSTAT_REG);
- splx(s);
if ((intstat & (INTR_PENDING|CMD_COMPLETE))
== (INTR_PENDING|CMD_COMPLETE)) {
@@ -1554,10 +1552,8 @@
*/
while (cmd_complete == 0 && --cmd_timeout) {
- s = splcam();
status = aha_inb(aha, STATUS_REG);
intstat = aha_inb(aha, INTSTAT_REG);
- splx(s);
if (aha->command_cmp != 0) {
cmd_complete = 1;
@@ -1602,9 +1598,7 @@
* Clear any pending interrupts. Block interrupts so our
* interrupt handler is not re-entered.
*/
- s = splcam();
aha_intr(aha);
- splx(s);
if (error != 0)
return (error);
@@ -1765,7 +1759,7 @@
static void
ahapoll(struct cam_sim *sim)
{
- aha_intr(cam_sim_softc(sim));
+ aha_intr_locked(cam_sim_softc(sim));
}
static void
@@ -1774,7 +1768,6 @@
struct aha_ccb *accb;
union ccb *ccb;
struct aha_softc *aha;
- int s;
uint32_t paddr;
struct ccb_hdr *ccb_h;
@@ -1781,16 +1774,14 @@
accb = (struct aha_ccb *)arg;
ccb = accb->ccb;
aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr;
+ mtx_assert(&aha->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out\n", (void *)accb);
- s = splcam();
-
if ((accb->flags & ACCB_ACTIVE) == 0) {
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out CCB already completed\n",
(void *)accb);
- splx(s);
return;
}
@@ -1815,7 +1806,7 @@
struct aha_ccb *pending_accb;
pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
- untimeout(ahatimeout, pending_accb, ccb_h->timeout_ch);
+ callout_stop(&pending_accb->timer);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
@@ -1844,7 +1835,7 @@
* later which will attempt a bus reset.
*/
accb->flags |= ACCB_DEVICE_RESET;
- ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, 2 * hz);
+ callout_reset(&accb->timer, 2 * hz, ahatimeout, accb);
aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET;
/* No Data Transfer */
@@ -1861,17 +1852,18 @@
aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
ahanextoutbox(aha);
}
-
- splx(s);
}
int
aha_detach(struct aha_softc *aha)
{
+ mtx_lock(&aha->lock);
xpt_async(AC_LOST_DEVICE, aha->path, NULL);
xpt_free_path(aha->path);
xpt_bus_deregister(cam_sim_path(aha->sim));
cam_sim_free(aha->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aha->lock);
+ /* XXX: Drain all timers? */
return (0);
}
MODULE_DEPEND(aha, cam, 1, 1, 1);
Modified: trunk/sys/dev/aha/aha_isa.c
===================================================================
--- trunk/sys/dev/aha/aha_isa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/aha/aha_isa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/aha/aha_isa.c,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*
* Product specific probe and attach routines for:
* Adaptec 154x.
@@ -110,7 +110,6 @@
struct aha_softc *aha = device_get_softc(dev);
int error;
u_long port_start;
- struct resource *port_res;
int port_rid;
int drq;
int irq;
@@ -122,20 +121,19 @@
return (ENXIO);
port_rid = 0;
- port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
- 0, ~0, AHA_NREGS, RF_ACTIVE);
+ aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
+ 0ul, ~0ul, AHA_NREGS, RF_ACTIVE);
- if (port_res == NULL)
+ if (aha->port == NULL)
return (ENXIO);
- port_start = rman_get_start(port_res);
- aha_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res),
- rman_get_bushandle(port_res));
+ port_start = rman_get_start(aha->port);
+ aha_alloc(aha);
/* See if there is really a card present */
if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
aha_free(aha);
- bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
+ bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port);
return (ENXIO);
}
@@ -152,11 +150,12 @@
(uintmax_t)port_start);
aha_free(aha);
bus_release_resource(dev, SYS_RES_IOPORT, port_rid,
- port_res);
+ aha->port);
return (ENXIO);
}
- bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
+ bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port);
+ aha->port = NULL;
switch (config_data.dma_chan) {
case DMA_CHAN_5:
@@ -189,17 +188,12 @@
aha_isa_attach(device_t dev)
{
struct aha_softc *aha = device_get_softc(dev);
- bus_dma_filter_t *filter;
- void *filter_arg;
- bus_addr_t lowaddr;
- void *ih;
int error = ENOMEM;
- int aha_free_needed = 0;
aha->dev = dev;
aha->portrid = 0;
aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &aha->portrid,
- 0, ~0, AHA_NREGS, RF_ACTIVE);
+ 0ul, ~0ul, AHA_NREGS, RF_ACTIVE);
if (!aha->port) {
device_printf(dev, "Unable to allocate I/O ports\n");
goto fail;
@@ -228,23 +222,19 @@
isa_dmacascade(rman_get_start(aha->drq));
/* Allocate our parent dmatag */
- filter = NULL;
- filter_arg = NULL;
- lowaddr = BUS_SPACE_MAXADDR_24BIT;
-
if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev),
/* alignemnt */ 1,
/* boundary */ 0,
- /* lowaddr */ lowaddr,
+ /* lowaddr */ BUS_SPACE_MAXADDR_24BIT,
/* highaddr */ BUS_SPACE_MAXADDR,
- /* filter */ filter,
- /* filterarg */ filter_arg,
+ /* filter */ NULL,
+ /* filterarg */ NULL,
/* maxsize */ BUS_SPACE_MAXSIZE_24BIT,
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->parent_dmat) != 0) {
device_printf(dev, "dma tag create failed.\n");
goto fail;
@@ -264,7 +254,6 @@
aha->ccb_sg_opcode = INITIATOR_SG_CCB;
aha->ccb_ccb_opcode = INITIATOR_CCB;
}
- aha_free_needed++;
error = aha_attach(aha);
if (error) {
@@ -272,20 +261,20 @@
goto fail;
}
- error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY,
- NULL, aha_intr, aha, &ih);
+ error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY|
+ INTR_MPSAFE, NULL, aha_intr, aha, &aha->ih);
if (error) {
device_printf(dev, "Unable to register interrupt handler\n");
+ aha_detach(aha);
goto fail;
}
return (0);
fail: ;
+ aha_free(aha);
bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
- if (aha_free_needed)
- aha_free(aha);
return (error);
}
@@ -299,10 +288,6 @@
if (error)
device_printf(dev, "failed to unregister interrupt handler\n");
- bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
- bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
- bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
-
error = aha_detach(aha);
if (error) {
device_printf(dev, "detach failed\n");
@@ -309,6 +294,9 @@
return (error);
}
aha_free(aha);
+ bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
+ bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
+ bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
return (0);
}
@@ -320,7 +308,6 @@
bus_addr_t ioport;
struct aha_softc aha;
int rid;
- struct resource *res;
device_t child;
/* Attempt to find an adapter */
@@ -335,12 +322,11 @@
* XXX kldload/kldunload.
*/
rid = 0;
- res = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
+ aha.port = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
ioport, ioport, AHA_NREGS, RF_ACTIVE);
- if (res == NULL)
+ if (aha.port == NULL)
continue;
- aha_alloc(&aha, -1, rman_get_bustag(res),
- rman_get_bushandle(res));
+ aha_alloc(&aha);
/* See if there is really a card present */
if (aha_probe(&aha) || aha_fetch_adapter_info(&aha))
goto not_this_one;
@@ -350,8 +336,8 @@
* Could query the board and set IRQ/DRQ, but probe does
* that.
*/
- not_this_one:;
- bus_release_resource(parent, SYS_RES_IOPORT, rid, res);
+ not_this_one:
+ bus_release_resource(parent, SYS_RES_IOPORT, rid, aha.port);
aha_free(&aha);
}
}
Modified: trunk/sys/dev/aha/aha_mca.c
===================================================================
--- trunk/sys/dev/aha/aha_mca.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/aha/aha_mca.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/aha/aha_mca.c,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1999 Matthew N. Dodd <winter at jurai.net>
* All rights reserved.
@@ -119,8 +119,6 @@
{
struct aha_softc * sc = device_get_softc(dev);
int error = ENOMEM;
- int unit = device_get_unit(dev);
- void * ih;
sc->portrid = 0;
sc->port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid,
@@ -146,8 +144,7 @@
goto bad;
}
- aha_alloc(sc, unit, rman_get_bustag(sc->port),
- rman_get_bushandle(sc->port));
+ aha_alloc(sc);
error = aha_probe(sc);
if (error) {
device_printf(dev, "aha_probe() failed!\n");
@@ -174,8 +171,8 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&sc->parent_dmat);
if (error) {
device_printf(dev, "bus_dma_tag_create() failed!\n");
@@ -194,10 +191,11 @@
goto bad;
}
- error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY,
- NULL, aha_intr, sc, &ih);
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, aha_intr, sc, &aha->ih);
if (error) {
device_printf(dev, "Unable to register interrupt handler\n");
+ aha_detach(sc);
goto bad;
}
Modified: trunk/sys/dev/aha/ahareg.h
===================================================================
--- trunk/sys/dev/aha/ahareg.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/aha/ahareg.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/aha/ahareg.h,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Generic register and struct definitions for the Adaptech 1540, 1542,
* 1640, 1642 SCSI host adapters. Product specific probe and attach
@@ -298,6 +298,7 @@
uint32_t flags;
union ccb *ccb;
bus_dmamap_t dmamap;
+ struct callout timer;
aha_sg_t *sg_list;
uint32_t sg_list_phys;
};
@@ -310,8 +311,6 @@
};
struct aha_softc {
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
struct cam_sim *sim;
struct cam_path *path;
aha_mbox_out_t *cur_outbox;
@@ -369,14 +368,15 @@
struct resource *irq;
struct resource *port;
struct resource *drq;
- int irqrid;
- int portrid;
- int drqrid;
- void **ih;
+ int irqrid;
+ int portrid;
+ int drqrid;
+ void *ih;
device_t dev;
+ struct mtx lock;
};
-void aha_alloc(struct aha_softc *, int, bus_space_tag_t, bus_space_handle_t);
+void aha_alloc(struct aha_softc *);
int aha_attach(struct aha_softc *);
int aha_cmd(struct aha_softc *, aha_op_t, uint8_t *, u_int, uint8_t *, u_int,
u_int);
@@ -390,11 +390,11 @@
#define DEFAULT_CMD_TIMEOUT 10000 /* 1 sec */
-#define aha_inb(aha, port) \
- bus_space_read_1((aha)->tag, (aha)->bsh, port)
+#define aha_inb(aha, reg) \
+ bus_read_1((aha)->port, reg)
-#define aha_outb(aha, port, value) \
- bus_space_write_1((aha)->tag, (aha)->bsh, port, value)
+#define aha_outb(aha, reg, value) \
+ bus_write_1((aha)->port, reg, value)
#define ADP0100_PNP 0x00019004 /* ADP0100 */
#define AHA1540_PNP 0x40159004 /* ADP1540 */
Modified: trunk/sys/dev/ahb/ahb.c
===================================================================
--- trunk/sys/dev/ahb/ahb.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/ahb/ahb.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/ahb/ahb.c,v 1.5 2009/01/18 19:29:04 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* CAM SCSI device driver for the Adaptec 174X SCSI Host adapter
*
@@ -30,6 +30,7 @@
*/
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -58,16 +59,16 @@
#define ccb_ahb_ptr spriv_ptr1
#define ahb_inb(ahb, port) \
- bus_space_read_1((ahb)->tag, (ahb)->bsh, port)
+ bus_read_1((ahb)->res, port)
#define ahb_inl(ahb, port) \
- bus_space_read_4((ahb)->tag, (ahb)->bsh, port)
+ bus_read_4((ahb)->res, port)
#define ahb_outb(ahb, port, value) \
- bus_space_write_1((ahb)->tag, (ahb)->bsh, port, value)
+ bus_write_1((ahb)->res, port, value)
#define ahb_outl(ahb, port, value) \
- bus_space_write_4((ahb)->tag, (ahb)->bsh, port, value)
+ bus_write_4((ahb)->res, port, value)
static const char *ahbmatch(eisa_id_t type);
static struct ahb_softc *ahballoc(device_t dev, struct resource *res);
@@ -83,12 +84,13 @@
static __inline void ahbdone(struct ahb_softc *ahb, u_int32_t mbox,
u_int intstat);
static void ahbintr(void *arg);
+static void ahbintr_locked(struct ahb_softc *ahb);
static bus_dmamap_callback_t ahbexecuteecb;
static void ahbaction(struct cam_sim *sim, union ccb *ccb);
static void ahbpoll(struct cam_sim *sim);
/* Our timeout handler */
-static timeout_t ahbtimeout;
+static void ahbtimeout(void *arg);
static __inline struct ecb* ahbecbget(struct ahb_softc *ahb);
static __inline void ahbecbfree(struct ahb_softc* ahb,
@@ -108,12 +110,11 @@
ahbecbget(struct ahb_softc *ahb)
{
struct ecb* ecb;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&ahb->lock, MA_OWNED);
if ((ecb = SLIST_FIRST(&ahb->free_ecbs)) != NULL)
SLIST_REMOVE_HEAD(&ahb->free_ecbs, links);
- splx(s);
return (ecb);
}
@@ -121,12 +122,11 @@
static __inline void
ahbecbfree(struct ahb_softc* ahb, struct ecb* ecb)
{
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&ahb->lock, MA_OWNED);
ecb->state = ECB_FREE;
SLIST_INSERT_HEAD(&ahb->free_ecbs, ecb, links);
- splx(s);
}
static __inline u_int32_t
@@ -176,7 +176,8 @@
DELAY(20);
}
if (loopmax == 0)
- panic("ahb%ld: adapter not taking commands\n", ahb->unit);
+ panic("%s: adapter not taking commands\n",
+ device_get_nameunit(ahb->dev));
ahb_outl(ahb, MBOXOUT0, mboxval);
ahb_outb(ahb, ATTN, attn_code);
@@ -260,21 +261,20 @@
*/
struct ahb_softc *ahb;
struct ecb* next_ecb;
- struct resource *io = 0;
- struct resource *irq = 0;
+ struct resource *io;
+ struct resource *irq;
int rid;
void *ih;
+ irq = NULL;
rid = 0;
io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
- if (!io) {
+ if (io == NULL) {
device_printf(dev, "No I/O space?!\n");
return ENOMEM;
}
- if ((ahb = ahballoc(dev, io)) == NULL) {
- goto error_exit2;
- }
+ ahb = ahballoc(dev, io);
if (ahbreset(ahb) != 0)
goto error_exit;
@@ -281,7 +281,7 @@
rid = 0;
irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
- if (!irq) {
+ if (irq == NULL) {
device_printf(dev, "Can't allocate interrupt\n");
goto error_exit;
}
@@ -304,7 +304,7 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &ahb->lock,
&ahb->buffer_dmat) != 0)
goto error_exit;
@@ -324,8 +324,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&ahb->ecb_dmat) != 0)
goto error_exit;
@@ -357,6 +357,7 @@
if (bus_dmamap_create(ahb->buffer_dmat, /*flags*/0,
&next_ecb->dmamap))
break;
+ callout_init_mtx(&next_ecb->timer, &ahb->lock, 0);
ecb_paddr = ahbecbvtop(ahb, next_ecb);
next_ecb->hecb.status_ptr = ahbstatuspaddr(ecb_paddr);
next_ecb->hecb.sense_ptr = ahbsensepaddr(ecb_paddr);
@@ -365,9 +366,6 @@
next_ecb++;
}
- if (ahb->num_ecbs == 0)
- goto error_exit;
-
ahb->init_level++;
/*
@@ -378,8 +376,8 @@
goto error_exit;
/* Enable our interrupt */
- if (bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY, NULL, ahbintr,
- ahb, &ih) != 0)
+ if (bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE,
+ NULL, ahbintr, ahb, &ih) != 0)
goto error_exit;
return (0);
@@ -387,15 +385,13 @@
error_exit:
/*
* The board's IRQ line will not be left enabled
- * if we can't intialize correctly, so its safe
+ * if we can't initialize correctly, so its safe
* to release the irq.
*/
ahbfree(ahb);
-error_exit2:
- if (io)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
- if (irq)
+ if (irq != NULL)
bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
return (-1);
}
@@ -404,22 +400,14 @@
{
struct ahb_softc *ahb;
- /*
- * Allocate a storage area for us
- */
- ahb = malloc(sizeof(struct ahb_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (!ahb) {
- device_printf(dev, "cannot malloc!\n");
- return (NULL);
- }
+ ahb = device_get_softc(dev);
SLIST_INIT(&ahb->free_ecbs);
LIST_INIT(&ahb->pending_ccbs);
- ahb->unit = device_get_unit(dev);
- ahb->tag = rman_get_bustag(res);
- ahb->bsh = rman_get_bushandle(res);
+ ahb->res = res;
ahb->disc_permitted = ~0;
ahb->tags_permitted = ~0;
ahb->dev = dev;
+ mtx_init(&ahb->lock, "ahb", NULL, MTX_DEF);
return (ahb);
}
@@ -442,7 +430,7 @@
case 0:
break;
}
- free(ahb, M_DEVBUF);
+ mtx_destroy(&ahb->lock);
}
/*
@@ -504,7 +492,9 @@
struct ecb *ecb;
u_int i;
- /* Remeber who are we on the scsi bus */
+ mtx_lock(&ahb->lock);
+
+ /* Remember who are we on the scsi bus */
ahb->scsi_id = ahb_inb(ahb, SCSIDEF) & HSCSIID;
/* Use extended translation?? */
@@ -525,14 +515,15 @@
/* Poll for interrupt completion */
for (i = 1000; ecb->state != ECB_FREE && i != 0; i--) {
- ahbintr(ahb);
+ ahbintr_locked(ahb);
DELAY(1000);
}
ahb->num_ecbs = MIN(ahb->num_ecbs,
ahb->ha_inq_data->scsi_data.spc2_flags);
- printf("ahb%ld: %.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n",
- ahb->unit, ahb->ha_inq_data->scsi_data.product,
+ device_printf(ahb->dev,
+ "%.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n",
+ ahb->ha_inq_data->scsi_data.product,
(ahb->ha_inq_data->scsi_data.flags & 0x4) ? "Differential"
: "Single Ended",
ahb->ha_inq_data->scsi_data.revision,
@@ -547,21 +538,25 @@
* Create the device queue for our SIM.
*/
devq = cam_simq_alloc(ahb->num_ecbs);
- if (devq == NULL)
+ if (devq == NULL) {
+ mtx_unlock(&ahb->lock);
return (ENOMEM);
+ }
/*
* Construct our SIM entry
*/
- ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb, ahb->unit,
- &Giant, 2, ahb->num_ecbs, devq);
+ ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb,
+ device_get_unit(ahb->dev), &ahb->lock, 2, ahb->num_ecbs, devq);
if (ahb->sim == NULL) {
cam_simq_free(devq);
+ mtx_unlock(&ahb->lock);
return (ENOMEM);
}
if (xpt_bus_register(ahb->sim, ahb->dev, 0) != CAM_SUCCESS) {
cam_sim_free(ahb->sim, /*free_devq*/TRUE);
+ mtx_unlock(&ahb->lock);
return (ENXIO);
}
@@ -570,6 +565,7 @@
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(ahb->sim));
cam_sim_free(ahb->sim, /*free_devq*/TRUE);
+ mtx_unlock(&ahb->lock);
return (ENXIO);
}
@@ -577,6 +573,7 @@
* Allow the board to generate interrupts.
*/
ahb_outb(ahb, INTDEF, ahb_inb(ahb, INTDEF) | INTEN);
+ mtx_unlock(&ahb->lock);
return (0);
}
@@ -588,8 +585,8 @@
u_int target_id;
if (ahb->immed_cmd == 0) {
- printf("ahb%ld: Immediate Command complete with no "
- " pending command\n", ahb->unit);
+ device_printf(ahb->dev, "Immediate Command complete with no "
+ " pending command\n");
return;
}
@@ -605,8 +602,7 @@
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
if (ccb->ccb_h.target_id == target_id
|| target_id == ahb->scsi_id) {
- untimeout(ahbtimeout, pending_ecb,
- ccb->ccb_h.timeout_ch);
+ callout_stop(&pending_ecb->timer);
LIST_REMOVE(&ccb->ccb_h, sim_links.le);
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
bus_dmamap_unload(ahb->buffer_dmat,
@@ -622,20 +618,20 @@
xpt_done(ccb);
} else if (ahb->immed_ecb != NULL) {
/* Re-instate timeout */
- ccb->ccb_h.timeout_ch =
- timeout(ahbtimeout, (caddr_t)pending_ecb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&pending_ecb->timer,
+ (ccb->ccb_h.timeout * hz) / 1000,
+ ahbtimeout, pending_ecb);
}
}
if (ahb->immed_ecb != NULL) {
ahb->immed_ecb = NULL;
- printf("ahb%ld: No longer in timeout\n", ahb->unit);
+ device_printf(ahb->dev, "No longer in timeout\n");
} else if (target_id == ahb->scsi_id)
- printf("ahb%ld: SCSI Bus Reset Delivered\n", ahb->unit);
+ device_printf(ahb->dev, "SCSI Bus Reset Delivered\n");
else
- printf("ahb%ld: Bus Device Reset Delibered to target %d\n",
- ahb->unit, target_id);
+ device_printf(ahb->dev,
+ "Bus Device Reset Delivered to target %d\n", target_id);
ahb->immed_cmd = 0;
}
@@ -765,8 +761,9 @@
ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
break;
case HS_INVALID_ECB_PARAM:
- printf("ahb%ld: opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n",
- ahb->unit, hecb->opcode, hecb->flag_word1, hecb->flag_word2);
+ device_printf(ahb->dev,
+ "opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n",
+ hecb->opcode, hecb->flag_word1, hecb->flag_word2);
ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
break;
case HS_DUP_TCB_RECEIVED:
@@ -773,8 +770,8 @@
case HS_INVALID_OPCODE:
case HS_INVALID_CMD_LINK:
case HS_PROGRAM_CKSUM_ERROR:
- panic("ahb%ld: Can't happen host status %x occurred",
- ahb->unit, status->ha_status);
+ panic("%s: Can't happen host status %x occurred",
+ device_get_nameunit(ahb->dev), status->ha_status);
break;
}
if (ccb->ccb_h.status != CAM_REQ_CMP) {
@@ -797,7 +794,7 @@
ccb = ecb->ccb;
if (ccb != NULL) {
- untimeout(ahbtimeout, ecb, ccb->ccb_h.timeout_ch);
+ callout_stop(&ecb->timer);
LIST_REMOVE(&ccb->ccb_h, sim_links.le);
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
@@ -822,8 +819,8 @@
} else {
/* Non CCB Command */
if ((intstat & INTSTAT_MASK) != INTSTAT_ECB_OK) {
- printf("ahb%ld: Command 0%x Failed %x:%x:%x\n",
- ahb->unit, ecb->hecb.opcode,
+ device_printf(ahb->dev, "Command 0%x Failed %x:%x:%x\n",
+ ecb->hecb.opcode,
*((u_int16_t*)&ecb->status),
ecb->status.ha_status, ecb->status.resid_count);
}
@@ -838,11 +835,19 @@
ahbintr(void *arg)
{
struct ahb_softc *ahb;
+
+ ahb = arg;
+ mtx_lock(&ahb->lock);
+ ahbintr_locked(ahb);
+ mtx_unlock(&ahb->lock);
+}
+
+static void
+ahbintr_locked(struct ahb_softc *ahb)
+{
u_int intstat;
u_int32_t mbox;
- ahb = (struct ahb_softc *)arg;
-
while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) {
/*
* Fetch information about this interrupt.
@@ -901,16 +906,17 @@
union ccb *ccb;
struct ahb_softc *ahb;
u_int32_t ecb_paddr;
- int s;
ecb = (struct ecb *)arg;
ccb = ecb->ccb;
ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr;
+ mtx_assert(&ahb->lock, MA_OWNED);
if (error != 0) {
if (error != EFBIG)
- printf("ahb%ld: Unexepected error 0x%x returned from "
- "bus_dmamap_load\n", ahb->unit, error);
+ device_printf(ahb->dev,
+ "Unexepected error 0x%x returned from "
+ "bus_dmamap_load\n", error);
if (ccb->ccb_h.status == CAM_REQ_INPROG) {
xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
@@ -962,8 +968,6 @@
ecb->hecb.data_len = 0;
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -973,7 +977,6 @@
bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap);
ahbecbfree(ahb, ecb);
xpt_done(ccb);
- splx(s);
return;
}
@@ -984,9 +987,8 @@
/* Tell the adapter about this command */
ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id);
- ccb->ccb_h.timeout_ch = timeout(ahbtimeout, (caddr_t)ecb,
- (ccb->ccb_h.timeout * hz) / 1000);
- splx(s);
+ callout_reset(&ecb->timer, (ccb->ccb_h.timeout * hz) / 1000, ahbtimeout,
+ ecb);
}
static void
@@ -997,6 +999,7 @@
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahbaction\n"));
ahb = (struct ahb_softc *)cam_sim_softc(sim);
+ mtx_assert(&ahb->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
/* Common cases first */
@@ -1065,10 +1068,8 @@
* to a single buffer.
*/
if ((ccb->ccb_h.flags & CAM_DATA_PHYS)==0) {
- int s;
int error;
- s = splsoftvm();
error = bus_dmamap_load(
ahb->buffer_dmat,
ecb->dmamap,
@@ -1087,7 +1088,6 @@
ccb->ccb_h.status |=
CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -1177,17 +1177,14 @@
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
{
int i;
- int s;
- s = splcam();
ahb->immed_cmd = IMMED_RESET;
ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id);
/* Poll for interrupt completion */
for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) {
DELAY(1000);
- ahbintr(cam_sim_softc(sim));
+ ahbintr_locked(cam_sim_softc(sim));
}
- splx(s);
break;
}
case XPT_CALC_GEOMETRY:
@@ -1264,21 +1261,18 @@
struct ecb *ecb;
union ccb *ccb;
struct ahb_softc *ahb;
- int s;
ecb = (struct ecb *)arg;
ccb = ecb->ccb;
ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr;
+ mtx_assert(&ahb->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("ECB %p - timed out\n", (void *)ecb);
- s = splcam();
-
if ((ecb->state & ECB_ACTIVE) == 0) {
xpt_print_path(ccb->ccb_h.path);
printf("ECB %p - timed out ECB already completed\n",
(void *)ecb);
- splx(s);
return;
}
/*
@@ -1299,13 +1293,11 @@
ecb->state |= ECB_RELEASE_SIMQ;
}
- ccb_h = LIST_FIRST(&ahb->pending_ccbs);
- while (ccb_h != NULL) {
+ LIST_FOREACH(ccb_h, &ahb->pending_ccbs, sim_links.le) {
struct ecb *pending_ecb;
pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr;
- untimeout(ahbtimeout, pending_ecb, ccb_h->timeout_ch);
- ccb_h = LIST_NEXT(ccb_h, sim_links.le);
+ callout_stop(&pending_ecb->timer);
}
/* Store for our interrupt handler */
@@ -1325,8 +1317,7 @@
xpt_print_path(ccb->ccb_h.path);
printf("Queuing BDR\n");
ecb->state |= ECB_DEVICE_RESET;
- ccb->ccb_h.timeout_ch =
- timeout(ahbtimeout, (caddr_t)ecb, 2 * hz);
+ callout_reset(&ecb->timer, 2 * hz, ahbtimeout, ecb);
ahb->immed_cmd = IMMED_RESET;
ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id);
@@ -1338,8 +1329,7 @@
xpt_print_path(ccb->ccb_h.path);
printf("Attempting SCSI Bus reset\n");
ecb->state |= ECB_SCSIBUS_RESET;
- ccb->ccb_h.timeout_ch =
- timeout(ahbtimeout, (caddr_t)ecb, 2 * hz);
+ callout_reset(&ecb->timer, 2 * hz, ahbtimeout, ecb);
ahb->immed_cmd = IMMED_RESET;
ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id);
} else {
@@ -1349,8 +1339,6 @@
/* Simulate the reset complete interrupt */
ahbhandleimmed(ahb, 0, ahb->scsi_id|INTSTAT_IMMED_OK);
}
-
- splx(s);
}
static device_method_t ahb_eisa_methods[] = {
@@ -1364,7 +1352,7 @@
static driver_t ahb_eisa_driver = {
"ahb",
ahb_eisa_methods,
- 1, /* unused */
+ sizeof(struct ahb_softc),
};
static devclass_t ahb_devclass;
Modified: trunk/sys/dev/ahb/ahbreg.h
===================================================================
--- trunk/sys/dev/ahb/ahbreg.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/ahb/ahbreg.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/ahb/ahbreg.h,v 1.2 2008/12/02 02:24:30 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Hardware structure definitions for the Adaptec 174X CAM SCSI device driver.
*
@@ -256,12 +256,13 @@
ecb_state state;
union ccb *ccb;
bus_dmamap_t dmamap;
+ struct callout timer;
};
struct ahb_softc {
device_t dev;
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
+ struct resource *res;
+ struct mtx lock;
struct cam_sim *sim;
struct cam_path *path;
SLIST_HEAD(,ecb) free_ecbs;
@@ -275,7 +276,6 @@
struct ecb *immed_ecb;
struct ha_inquiry_data *ha_inq_data;
u_int32_t ha_inq_physbase;
- u_long unit;
u_int init_level;
u_int scsi_id;
u_int num_ecbs;
Modified: trunk/sys/dev/buslogic/bt.c
===================================================================
--- trunk/sys/dev/buslogic/bt.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/buslogic/bt.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -44,6 +44,7 @@
*/
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
@@ -141,6 +142,7 @@
static bus_dmamap_callback_t btexecuteccb;
static void btdone(struct bt_softc *bt, struct bt_ccb *bccb,
bt_mbi_comp_code_t comp_code);
+static void bt_intr_locked(struct bt_softc *bt);
/* Host adapter command functions */
static int btreset(struct bt_softc* bt, int hard_reset);
@@ -162,10 +164,8 @@
static void btpoll(struct cam_sim *sim);
/* Our timeout handler */
-timeout_t bttimeout;
+static void bttimeout(void *arg);
-u_long bt_unit = 0;
-
/*
* XXX
* Do our own re-probe protection until a configuration
@@ -207,12 +207,10 @@
LIST_INIT(&bt->pending_ccbs);
SLIST_INIT(&bt->sg_maps);
bt->dev = dev;
- bt->unit = device_get_unit(dev);
bt->port = port;
bt->irq = irq;
bt->drq = drq;
- bt->tag = rman_get_bustag(port);
- bt->bsh = rman_get_bushandle(port);
+ mtx_init(&bt->lock, "bt", NULL, MTX_DEF);
}
void
@@ -271,6 +269,7 @@
case 0:
break;
}
+ mtx_destroy(&bt->lock);
}
int
@@ -288,9 +287,11 @@
* Determine our IRQ, and DMA settings and
* export them to the configuration system.
*/
+ mtx_lock(&bt->lock);
error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
(u_int8_t*)&config_data, sizeof(config_data),
DEFAULT_CMD_TIMEOUT);
+ mtx_unlock(&bt->lock);
if (error != 0) {
printf("bt_port_probe: Could not determine IRQ or DMA "
"settings for adapter.\n");
@@ -382,7 +383,9 @@
* adapter and attempt to fetch the extended setup
* information. This should filter out all 1542 cards.
*/
+ mtx_lock(&bt->lock);
if ((error = btreset(bt, /*hard_reset*/TRUE)) != 0) {
+ mtx_unlock(&bt->lock);
if (bootverbose)
device_printf(dev, "Failed Reset\n");
return (ENXIO);
@@ -392,6 +395,7 @@
error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, ¶m, /*parmlen*/1,
(u_int8_t*)&esetup_info, sizeof(esetup_info),
DEFAULT_CMD_TIMEOUT);
+ mtx_unlock(&bt->lock);
if (error != 0) {
return (ENXIO);
}
@@ -413,10 +417,12 @@
u_int8_t length_param;
/* First record the firmware version */
+ mtx_lock(&bt->lock);
error = bt_cmd(bt, BOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0,
(u_int8_t*)&board_id, sizeof(board_id),
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
device_printf(dev, "bt_fetch_adapter_info - Failed Get Board Info\n");
return (error);
}
@@ -435,6 +441,7 @@
(u_int8_t*)&bt->firmware_ver[3], 1,
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
device_printf(dev,
"bt_fetch_adapter_info - Failed Get "
"Firmware 3rd Digit\n");
@@ -451,6 +458,7 @@
(u_int8_t*)&bt->firmware_ver[4], 1,
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
device_printf(dev,
"bt_fetch_adapter_info - Failed Get "
"Firmware 4th Digit\n");
@@ -484,6 +492,7 @@
(u_int8_t*)&esetup_info, sizeof(esetup_info),
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
return (error);
}
@@ -515,6 +524,7 @@
(u_int8_t*)&model_data, sizeof(model_data),
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
device_printf(dev,
"bt_fetch_adapter_info - Failed Inquire "
"Model Number\n");
@@ -601,6 +611,7 @@
sizeof(auto_scsi_data), DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
device_printf(dev,
"bt_fetch_adapter_info - Failed "
"Get Auto SCSI Info\n");
@@ -636,6 +647,7 @@
sizeof(setup_info), DEFAULT_CMD_TIMEOUT);
if (error != 0) {
+ mtx_unlock(&bt->lock);
device_printf(dev,
"bt_fetch_adapter_info - Failed "
"Get Setup Info\n");
@@ -663,6 +675,7 @@
error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
(u_int8_t*)&config_data, sizeof(config_data),
DEFAULT_CMD_TIMEOUT);
+ mtx_unlock(&bt->lock);
if (error != 0) {
device_printf(dev,
"bt_fetch_adapter_info - Failed Get Config\n");
@@ -721,7 +734,7 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &bt->lock,
&bt->buffer_dmat) != 0) {
goto error_exit;
}
@@ -741,8 +754,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->mailbox_dmat) != 0) {
goto error_exit;
}
@@ -768,7 +781,9 @@
bt->in_boxes = (bt_mbox_in_t *)&bt->out_boxes[bt->num_boxes];
+ mtx_lock(&bt->lock);
btinitmboxes(bt);
+ mtx_unlock(&bt->lock);
/* DMA tag for our ccb structures */
if (bus_dma_tag_create( /* parent */ bt->parent_dmat,
@@ -783,8 +798,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->ccb_dmat) != 0) {
goto error_exit;
}
@@ -819,8 +834,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->sg_dmat) != 0) {
goto error_exit;
}
@@ -838,7 +853,7 @@
}
/*
- * Note that we are going and return (to probe)
+ * Note that we are going and return (to attach)
*/
return 0;
@@ -874,15 +889,17 @@
/*
* Construct our SIM entry
*/
- bt->sim = cam_sim_alloc(btaction, btpoll, "bt", bt, bt->unit,
- &Giant, 2, tagged_dev_openings, devq);
+ bt->sim = cam_sim_alloc(btaction, btpoll, "bt", bt,
+ device_get_unit(bt->dev), &bt->lock, 2, tagged_dev_openings, devq);
if (bt->sim == NULL) {
cam_simq_free(devq);
return (ENOMEM);
}
-
+
+ mtx_lock(&bt->lock);
if (xpt_bus_register(bt->sim, dev, 0) != CAM_SUCCESS) {
cam_sim_free(bt->sim, /*free_devq*/TRUE);
+ mtx_unlock(&bt->lock);
return (ENXIO);
}
@@ -891,14 +908,16 @@
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(bt->sim));
cam_sim_free(bt->sim, /*free_devq*/TRUE);
+ mtx_unlock(&bt->lock);
return (ENXIO);
}
+ mtx_unlock(&bt->lock);
/*
* Setup interrupt.
*/
- error = bus_setup_intr(dev, bt->irq, INTR_TYPE_CAM|INTR_ENTROPY, NULL,
- bt_intr, bt, &bt->ih);
+ error = bus_setup_intr(dev, bt->irq, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, bt_intr, bt, &bt->ih);
if (error) {
device_printf(dev, "bus_setup_intr() failed: %d\n", error);
return (error);
@@ -1025,6 +1044,7 @@
next_ccb->sg_list = segs;
next_ccb->sg_list_phys = physaddr;
next_ccb->flags = BCCB_FREE;
+ callout_init_mtx(&next_ccb->timer, &bt->lock, 0);
error = bus_dmamap_create(bt->buffer_dmat, /*flags*/0,
&next_ccb->dmamap);
if (error != 0)
@@ -1052,9 +1072,9 @@
static __inline void
btfreeccb(struct bt_softc *bt, struct bt_ccb *bccb)
{
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&bt->lock, MA_OWNED);
if ((bccb->flags & BCCB_ACTIVE) != 0)
LIST_REMOVE(&bccb->ccb->ccb_h, sim_links.le);
if (bt->resource_shortage != 0
@@ -1065,7 +1085,6 @@
bccb->flags = BCCB_FREE;
SLIST_INSERT_HEAD(&bt->free_bt_ccbs, bccb, links);
bt->active_ccbs--;
- splx(s);
}
static __inline struct bt_ccb*
@@ -1072,9 +1091,9 @@
btgetccb(struct bt_softc *bt)
{
struct bt_ccb* bccb;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&bt->lock, MA_OWNED);
if ((bccb = SLIST_FIRST(&bt->free_bt_ccbs)) != NULL) {
SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
bt->active_ccbs++;
@@ -1086,7 +1105,6 @@
bt->active_ccbs++;
}
}
- splx(s);
return (bccb);
}
@@ -1099,6 +1117,7 @@
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("btaction\n"));
bt = (struct bt_softc *)cam_sim_softc(sim);
+ mtx_assert(&bt->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
/* Common cases first */
@@ -1112,11 +1131,8 @@
* get a bccb to use.
*/
if ((bccb = btgetccb(bt)) == NULL) {
- int s;
- s = splcam();
bt->resource_shortage = TRUE;
- splx(s);
xpt_freeze_simq(bt->sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@@ -1198,10 +1214,8 @@
* to a single buffer.
*/
if ((ccbh->flags & CAM_DATA_PHYS)==0) {
- int s;
int error;
- s = splsoftvm();
error = bus_dmamap_load(
bt->buffer_dmat,
bccb->dmamap,
@@ -1223,7 +1237,6 @@
csio->ccb_h.status |=
CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -1427,7 +1440,6 @@
struct bt_ccb *bccb;
union ccb *ccb;
struct bt_softc *bt;
- int s;
bccb = (struct bt_ccb *)arg;
ccb = bccb->ccb;
@@ -1485,8 +1497,6 @@
bccb->hccb.data_addr = 0;
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -1496,7 +1506,6 @@
bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap);
btfreeccb(bt, bccb);
xpt_done(ccb);
- splx(s);
return;
}
@@ -1504,9 +1513,8 @@
ccb->ccb_h.status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&bt->pending_ccbs, &ccb->ccb_h, sim_links.le);
- ccb->ccb_h.timeout_ch =
- timeout(bttimeout, (caddr_t)bccb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&bccb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+ bttimeout, bccb);
/* Tell the adapter about this command */
bt->cur_outbox->ccb_addr = btccbvtop(bt, bccb);
@@ -1522,7 +1530,7 @@
"Encountered busy mailbox with %d out of %d "
"commands active!!!\n", bt->active_ccbs,
bt->max_ccbs);
- untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch);
+ callout_stop(&bccb->timer);
if (nseg != 0)
bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap);
btfreeccb(bt, bccb);
@@ -1535,7 +1543,6 @@
bt->cur_outbox->action_code = BMBO_START;
bt_outb(bt, COMMAND_REG, BOP_START_MBOX);
btnextoutbox(bt);
- splx(s);
}
void
@@ -1542,9 +1549,18 @@
bt_intr(void *arg)
{
struct bt_softc *bt;
+
+ bt = arg;
+ mtx_lock(&bt->lock);
+ bt_intr_locked(bt);
+ mtx_unlock(&bt->lock);
+}
+
+void
+bt_intr_locked(struct bt_softc *bt)
+{
u_int intstat;
- bt = (struct bt_softc *)arg;
while (((intstat = bt_inb(bt, INTSTAT_REG)) & INTR_PENDING) != 0) {
if ((intstat & CMD_COMPLETE) != 0) {
@@ -1630,9 +1646,9 @@
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
btdone(bt, pending_bccb, BMBI_ERROR);
} else {
- ccb_h->timeout_ch =
- timeout(bttimeout, (caddr_t)pending_bccb,
- (ccb_h->timeout * hz) / 1000);
+ callout_reset(&pending_bccb->timer,
+ (ccb_h->timeout * hz) / 1000,
+ bttimeout, pending_bccb);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
@@ -1640,7 +1656,7 @@
return;
}
- untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch);
+ callout_stop(&bccb->timer);
switch (comp_code) {
case BMBI_FREE:
@@ -1823,8 +1839,9 @@
}
if (timeout == 0) {
if (bootverbose)
- printf("%s: btreset - Diagnostic Active failed to "
- "assert. status = 0x%x\n", bt_name(bt), status);
+ device_printf(bt->dev,
+ "btreset - Diagnostic Active failed to "
+ "assert. status = 0x%x\n", status);
return (ETIMEDOUT);
}
@@ -1851,8 +1868,9 @@
DELAY(100);
}
if (timeout == 0) {
- printf("%s: btreset - Host adapter failed to come ready. "
- "status = 0x%x\n", bt_name(bt), status);
+ device_printf(bt->dev,
+ "btreset - Host adapter failed to come ready. "
+ "status = 0x%x\n", status);
return (ETIMEDOUT);
}
@@ -1859,12 +1877,13 @@
/* If the diagnostics failed, tell the user */
if ((status & DIAG_FAIL) != 0
|| (status & HA_READY) == 0) {
- printf("%s: btreset - Adapter failed diagnostics\n",
- bt_name(bt));
+ device_printf(bt->dev,
+ "btreset - Adapter failed diagnostics\n");
if ((status & DATAIN_REG_READY) != 0)
- printf("%s: btreset - Host Adapter Error code = 0x%x\n",
- bt_name(bt), bt_inb(bt, DATAIN_REG));
+ device_printf(bt->dev,
+ "btreset - Host Adapter Error code = 0x%x\n",
+ bt_inb(bt, DATAIN_REG));
return (ENXIO);
}
@@ -1902,7 +1921,6 @@
u_int saved_status;
u_int intstat;
u_int reply_buf_size;
- int s;
int cmd_complete;
int error;
@@ -1935,8 +1953,9 @@
DELAY(100);
}
if (timeout == 0) {
- printf("%s: bt_cmd: Timeout waiting for adapter ready, "
- "status = 0x%x\n", bt_name(bt), status);
+ device_printf(bt->dev,
+ "bt_cmd: Timeout waiting for adapter ready, "
+ "status = 0x%x\n", status);
return (ETIMEDOUT);
}
@@ -1952,10 +1971,8 @@
timeout = 10000;
while (param_len && --timeout) {
DELAY(100);
- s = splcam();
status = bt_inb(bt, STATUS_REG);
intstat = bt_inb(bt, INTSTAT_REG);
- splx(s);
if ((intstat & (INTR_PENDING|CMD_COMPLETE))
== (INTR_PENDING|CMD_COMPLETE)) {
@@ -1977,8 +1994,8 @@
}
}
if (timeout == 0) {
- printf("%s: bt_cmd: Timeout sending parameters, "
- "status = 0x%x\n", bt_name(bt), status);
+ device_printf(bt->dev, "bt_cmd: Timeout sending parameters, "
+ "status = 0x%x\n", status);
cmd_complete = 1;
saved_status = status;
error = ETIMEDOUT;
@@ -1989,7 +2006,6 @@
*/
while (cmd_complete == 0 && --cmd_timeout) {
- s = splcam();
status = bt_inb(bt, STATUS_REG);
intstat = bt_inb(bt, INTSTAT_REG);
/*
@@ -2001,8 +2017,7 @@
*/
if ((intstat & (INTR_PENDING|IMB_LOADED))
== (INTR_PENDING|IMB_LOADED))
- bt_intr(bt);
- splx(s);
+ bt_intr_locked(bt);
if (bt->command_cmp != 0) {
/*
@@ -2036,9 +2051,9 @@
if (reply_len < reply_buf_size) {
*reply_data++ = data;
} else {
- printf("%s: bt_cmd - Discarded reply data byte "
- "for opcode 0x%x\n", bt_name(bt),
- opcode);
+ device_printf(bt->dev,
+ "bt_cmd - Discarded reply data byte "
+ "for opcode 0x%x\n", opcode);
}
/*
* Reset timeout to ensure at least a second
@@ -2055,20 +2070,18 @@
DELAY(100);
}
if (cmd_timeout == 0) {
- printf("%s: bt_cmd: Timeout waiting for command (%x) "
- "to complete.\n%s: status = 0x%x, intstat = 0x%x, "
- "rlen %d\n", bt_name(bt), opcode,
- bt_name(bt), status, intstat, reply_len);
+ device_printf(bt->dev,
+ "bt_cmd: Timeout waiting for command (%x) "
+ "to complete.\n", opcode);
+ device_printf(bt->dev, "status = 0x%x, intstat = 0x%x, "
+ "rlen %d\n", status, intstat, reply_len);
error = (ETIMEDOUT);
}
/*
- * Clear any pending interrupts. Block interrupts so our
- * interrupt handler is not re-entered.
+ * Clear any pending interrupts.
*/
- s = splcam();
- bt_intr(bt);
- splx(s);
+ bt_intr_locked(bt);
if (error != 0)
return (error);
@@ -2084,7 +2097,7 @@
* reset above), perform a soft reset.
*/
if (bootverbose)
- printf("%s: Invalid Command 0x%x\n", bt_name(bt),
+ device_printf(bt->dev, "Invalid Command 0x%x\n",
opcode);
DELAY(1000);
status = bt_inb(bt, STATUS_REG);
@@ -2152,8 +2165,8 @@
printf("btinitmboxes: Unable to enable strict RR\n");
error = 0;
} else if (bootverbose) {
- printf("%s: Using Strict Round Robin Mailbox Mode\n",
- bt_name(bt));
+ device_printf(bt->dev,
+ "Using Strict Round Robin Mailbox Mode\n");
}
}
@@ -2200,8 +2213,9 @@
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
- printf("%s: btfetchtransinfo - Inquire Setup Info Failed %x\n",
- bt_name(bt), error);
+ device_printf(bt->dev,
+ "btfetchtransinfo - Inquire Setup Info Failed %x\n",
+ error);
return;
}
@@ -2255,8 +2269,9 @@
DEFAULT_CMD_TIMEOUT);
if (error != 0) {
- printf("%s: btfetchtransinfo - Inquire Sync "
- "Info Failed 0x%x\n", bt_name(bt), error);
+ device_printf(bt->dev,
+ "btfetchtransinfo - Inquire Sync "
+ "Info Failed 0x%x\n", error);
return;
}
sync_period = sync_info.sync_rate[target] * 100;
@@ -2317,7 +2332,7 @@
static void
btpoll(struct cam_sim *sim)
{
- bt_intr(cam_sim_softc(sim));
+ bt_intr_locked(cam_sim_softc(sim));
}
void
@@ -2326,21 +2341,18 @@
struct bt_ccb *bccb;
union ccb *ccb;
struct bt_softc *bt;
- int s;
bccb = (struct bt_ccb *)arg;
ccb = bccb->ccb;
bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr;
+ mtx_assert(&bt->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out\n", (void *)bccb);
- s = splcam();
-
if ((bccb->flags & BCCB_ACTIVE) == 0) {
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out CCB already completed\n",
(void *)bccb);
- splx(s);
return;
}
@@ -2367,7 +2379,7 @@
struct bt_ccb *pending_bccb;
pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr;
- untimeout(bttimeout, pending_bccb, ccb_h->timeout_ch);
+ callout_stop(&pending_bccb->timer);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
@@ -2390,7 +2402,7 @@
*/
ccb->ccb_h.status = CAM_CMD_TIMEOUT;
btreset(bt, /*hardreset*/TRUE);
- printf("%s: No longer in timeout\n", bt_name(bt));
+ device_printf(bt->dev, "No longer in timeout\n");
} else {
/*
* Send a Bus Device Reset message:
@@ -2404,8 +2416,7 @@
* later which will attempt a bus reset.
*/
bccb->flags |= BCCB_DEVICE_RESET;
- ccb->ccb_h.timeout_ch =
- timeout(bttimeout, (caddr_t)bccb, 2 * hz);
+ callout_reset(&bccb->timer, 2 * hz, bttimeout, bccb);
bt->recovery_bccb->hccb.opcode = INITIATOR_BUS_DEV_RESET;
@@ -2422,8 +2433,6 @@
bt_outb(bt, COMMAND_REG, BOP_START_MBOX);
btnextoutbox(bt);
}
-
- splx(s);
}
MODULE_VERSION(bt, 1);
Modified: trunk/sys/dev/buslogic/bt_eisa.c
===================================================================
--- trunk/sys/dev/buslogic/bt_eisa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/buslogic/bt_eisa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/buslogic/bt_eisa.c,v 1.2 2008/12/02 02:24:37 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Product specific probe and attach routines for:
* Buslogic BT74x SCSI controllers
@@ -141,7 +141,7 @@
return (ENOMEM);
}
} else
- irq = 0;
+ irq = NULL;
bt->irq = irq;
return (0);
@@ -288,7 +288,7 @@
result = ENXIO;
} else {
eisa_add_intr(dev, info.irq, shared);
- result = 0;
+ result = BUS_PROBE_DEFAULT;
}
bt_eisa_release_resources(dev);
@@ -316,11 +316,11 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg, */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg, */ NULL,
&bt->parent_dmat) != 0) {
bt_eisa_release_resources(dev);
- return -1;
+ return (ENOMEM);
}
/*
@@ -329,7 +329,7 @@
*/
if (bt_probe(dev) || bt_fetch_adapter_info(dev) || bt_init(dev)) {
bt_eisa_release_resources(dev);
- return -1;
+ return (ENXIO);
}
/* Attach sub-devices - always succeeds (sets up intr) */
Modified: trunk/sys/dev/buslogic/bt_isa.c
===================================================================
--- trunk/sys/dev/buslogic/bt_isa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/buslogic/bt_isa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/buslogic/bt_isa.c,v 1.2 2008/12/02 02:24:37 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Product specific probe and attach routines for:
* Buslogic BT-54X and BT-445 cards
@@ -76,7 +76,7 @@
return (ENOMEM);
}
} else
- irq = 0;
+ irq = NULL;
if (isa_get_drq(dev) != -1) {
rid = 0;
@@ -91,7 +91,7 @@
return (ENOMEM);
}
} else
- drq = 0;
+ drq = NULL;
bt_init_softc(dev, port, irq, drq);
@@ -177,7 +177,7 @@
bus_set_resource(dev, SYS_RES_DRQ, 0, info.drq, 1);
bus_set_resource(dev, SYS_RES_IRQ, 0, info.irq, 1);
- return (0);
+ return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
@@ -234,7 +234,7 @@
}
/* XXX Should be a child of the ISA or VL bus dma tag */
- if (bus_dma_tag_create( /* parent */ NULL,
+ if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev),
/* alignemnt */ 1,
/* boundary */ 0,
/* lowaddr */ lowaddr,
@@ -245,8 +245,8 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->parent_dmat) != 0) {
bt_isa_release_resources(dev);
return (ENOMEM);
@@ -273,8 +273,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->sense_dmat) != 0) {
bt_isa_release_resources(dev);
return (ENOMEM);
Modified: trunk/sys/dev/buslogic/bt_mca.c
===================================================================
--- trunk/sys/dev/buslogic/bt_mca.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/buslogic/bt_mca.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/buslogic/bt_mca.c,v 1.2 2008/12/02 02:24:37 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Copyright (c) 1999 Matthew N. Dodd <winter at jurai.net>
* All rights reserved.
@@ -197,7 +197,7 @@
} else {
mca_add_drq(dev, drq);
mca_add_irq(dev, irq);
- result = 0;
+ result = BUS_PROBE_DEFAULT;
}
bt_mca_release_resources(dev);
@@ -230,8 +230,8 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->parent_dmat) != 0) {
bt_mca_release_resources(dev);
return (ENOMEM);
@@ -255,8 +255,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->sense_dmat) != 0) {
bt_mca_release_resources(dev);
return (ENOMEM);
Modified: trunk/sys/dev/buslogic/bt_pci.c
===================================================================
--- trunk/sys/dev/buslogic/bt_pci.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/buslogic/bt_pci.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/buslogic/bt_pci.c,v 1.2 2008/12/02 02:24:37 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Product specific probe and attach routines for:
* Buslogic BT946, BT948, BT956, BT958 SCSI controllers
@@ -149,7 +149,7 @@
}
bt_pci_release_resources(dev);
device_set_desc(dev, "Buslogic Multi-Master SCSI Host Adapter");
- return (0);
+ return (BUS_PROBE_DEFAULT);
}
default:
break;
@@ -162,7 +162,6 @@
bt_pci_attach(device_t dev)
{
struct bt_softc *bt = device_get_softc(dev);
- int opri;
int error;
/* Initialize softc */
@@ -184,31 +183,19 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&bt->parent_dmat) != 0) {
bt_pci_release_resources(dev);
return (ENOMEM);
}
- /*
- * Protect ourself from spurrious interrupts during
- * intialization and attach. We should really rely
- * on interrupts during attach, but we don't have
- * access to our interrupts during ISA probes, so until
- * that changes, we mask our interrupts during attach
- * too.
- */
- opri = splcam();
-
if (bt_probe(dev) || bt_fetch_adapter_info(dev) || bt_init(dev)) {
bt_pci_release_resources(dev);
- splx(opri);
return (ENXIO);
}
error = bt_attach(dev);
- splx(opri);
if (error) {
bt_pci_release_resources(dev);
Modified: trunk/sys/dev/buslogic/btreg.h
===================================================================
--- trunk/sys/dev/buslogic/btreg.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/buslogic/btreg.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/dev/buslogic/btreg.h,v 1.2 2008/12/02 02:24:37 laffer1 Exp $ */
+/* $MidnightBSD$ */
/*-
* Generic register and struct definitions for the BusLogic
* MultiMaster SCSI host adapters. Product specific probe and
@@ -583,6 +583,7 @@
u_int32_t flags;
union ccb *ccb;
bus_dmamap_t dmamap;
+ struct callout timer;
bt_sg_t *sg_list;
u_int32_t sg_list_phys;
};
@@ -600,8 +601,7 @@
struct resource *irq;
struct resource *drq;
void *ih;
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
+ struct mtx lock;
struct cam_sim *sim;
struct cam_path *path;
bt_mbox_out_t *cur_outbox;
@@ -638,7 +638,6 @@
u_int num_ccbs; /* Number of CCBs malloc'd */
u_int max_ccbs; /* Maximum allocatable CCBs */
u_int max_sg;
- u_int unit;
u_int scsi_id;
u_int32_t extended_trans :1,
wide_bus :1,
@@ -665,8 +664,6 @@
char model[5];
};
-extern u_long bt_unit;
-
#define BT_TEMP_UNIT 0xFF /* Unit for probes */
void bt_init_softc(device_t dev,
struct resource *port,
@@ -697,10 +694,10 @@
#define bt_name(bt) device_get_nameunit(bt->dev)
-#define bt_inb(bt, port) \
- bus_space_read_1((bt)->tag, (bt)->bsh, port)
+#define bt_inb(bt, reg) \
+ bus_read_1((bt)->port, reg)
-#define bt_outb(bt, port, value) \
- bus_space_write_1((bt)->tag, (bt)->bsh, port, value)
+#define bt_outb(bt, reg, value) \
+ bus_write_1((bt)->port, reg, value)
#endif /* _BT_H_ */
Modified: trunk/sys/dev/dpt/dpt.h
===================================================================
--- trunk/sys/dev/dpt/dpt.h 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/dpt/dpt.h 2017-03-05 19:38:53 UTC (rev 9462)
@@ -876,6 +876,7 @@
typedef struct dpt_ccb {
eata_ccb_t eata_ccb;
bus_dmamap_t dmamap;
+ struct callout timer;
dpt_sg_t *sg_list;
u_int32_t sg_busaddr;
dccb_state state;
@@ -1017,6 +1018,7 @@
/* Main state machine and interface structure */
typedef struct dpt_softc {
device_t dev;
+ struct mtx lock;
struct resource * io_res;
int io_rid;
@@ -1030,8 +1032,6 @@
struct resource * drq_res;
int drq_rid;
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
dpt_ccb_t *dpt_dccbs; /* Array of dpt ccbs */
bus_addr_t dpt_ccb_busbase; /* phys base address of array */
@@ -1079,7 +1079,6 @@
u_int8_t dma_channel;
TAILQ_ENTRY(dpt_softc) links;
- int unit;
int init_level;
/*
@@ -1275,9 +1274,6 @@
(end.tv_usec - start.tv_usec) );
}
-extern TAILQ_HEAD(dpt_softc_list, dpt_softc) dpt_softcs;
-
-extern int dpt_controllers_present;
extern devclass_t dpt_devclass;
#ifdef _KERNEL
Modified: trunk/sys/dev/dpt/dpt_eisa.c
===================================================================
--- trunk/sys/dev/dpt/dpt_eisa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/dpt/dpt_eisa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -105,11 +105,11 @@
dpt_eisa_attach (device_t dev)
{
dpt_softc_t * dpt;
- int s;
int error = 0;
dpt = device_get_softc(dev);
dpt->dev = dev;
+ dpt_alloc(dev);
dpt->io_rid = 0;
dpt->io_type = SYS_RES_IOPORT;
@@ -120,11 +120,8 @@
goto bad;
}
- dpt_alloc(dev);
-
/* Allocate a dmatag representing the capabilities of this attachment */
- /* XXX Should be a child of the EISA bus dma tag */
- if (bus_dma_tag_create( /* parent */ NULL,
+ if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev),
/* alignemnt */ 1,
/* boundary */ 0,
/* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
@@ -135,17 +132,14 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&dpt->parent_dmat) != 0) {
error = ENXIO;
goto bad;
}
- s = splcam();
-
if (dpt_init(dpt) != 0) {
- splx(s);
error = ENXIO;
goto bad;
}
@@ -153,10 +147,8 @@
/* Register with the XPT */
dpt_attach(dpt);
- splx(s);
-
- if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
- NULL, dpt_intr, dpt, &dpt->ih)) {
+ if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
goto bad;
Modified: trunk/sys/dev/dpt/dpt_isa.c
===================================================================
--- trunk/sys/dev/dpt/dpt_isa.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/dpt/dpt_isa.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -31,7 +31,9 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -150,11 +152,11 @@
dpt_isa_attach (device_t dev)
{
dpt_softc_t * dpt;
- int s;
int error = 0;
dpt = device_get_softc(dev);
dpt->dev = dev;
+ dpt_alloc(dev);
dpt->io_rid = 0;
dpt->io_type = SYS_RES_IOPORT;
@@ -176,10 +178,8 @@
isa_dma_acquire(rman_get_start(dpt->drq_res));
isa_dmacascade(rman_get_start(dpt->drq_res));
- dpt_alloc(dev);
-
/* Allocate a dmatag representing the capabilities of this attachment */
- if (bus_dma_tag_create( /* parent */ NULL,
+ if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev),
/* alignemnt */ 1,
/* boundary */ 0,
/* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
@@ -190,17 +190,14 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&dpt->parent_dmat) != 0) {
error = ENXIO;
goto bad;
}
- s = splcam();
-
if (dpt_init(dpt) != 0) {
- splx(s);
error = ENXIO;
goto bad;
}
@@ -208,10 +205,8 @@
/* Register with the XPT */
dpt_attach(dpt);
- splx(s);
-
- if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
- dpt_intr, dpt, &dpt->ih)) {
+ if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
goto bad;
Modified: trunk/sys/dev/dpt/dpt_pci.c
===================================================================
--- trunk/sys/dev/dpt/dpt_pci.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/dpt/dpt_pci.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -75,7 +75,6 @@
dpt_pci_attach (device_t dev)
{
dpt_softc_t * dpt;
- int s;
int error = 0;
u_int32_t command;
@@ -82,6 +81,7 @@
dpt = device_get_softc(dev);
dpt->dev = dev;
+ dpt_alloc(dev);
command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
@@ -117,8 +117,7 @@
}
/* Ensure busmastering is enabled */
- command |= PCIM_CMD_BUSMASTEREN;
- pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
+ pci_enable_busmaster(dev);
if (rman_get_start(dpt->io_res) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) {
#ifdef DPT_DEBUG_WARN
@@ -129,8 +128,6 @@
goto bad;
}
- dpt_alloc(dev);
-
/* Allocate a dmatag representing the capabilities of this attachment */
if (bus_dma_tag_create( /* PCI parent */ bus_get_dma_tag(dev),
/* alignemnt */ 1,
@@ -143,15 +140,13 @@
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&dpt->parent_dmat) != 0) {
error = ENXIO;
goto bad;
}
- s = splcam();
-
if (dpt_init(dpt) != 0) {
error = ENXIO;
goto bad;
@@ -160,10 +155,8 @@
/* Register with the XPT */
dpt_attach(dpt);
- splx(s);
-
- if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
- NULL, dpt_intr, dpt, &dpt->ih)) {
+ if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
goto bad;
Modified: trunk/sys/dev/dpt/dpt_scsi.c
===================================================================
--- trunk/sys/dev/dpt/dpt_scsi.c 2017-03-05 19:38:12 UTC (rev 9461)
+++ trunk/sys/dev/dpt/dpt_scsi.c 2017-03-05 19:38:53 UTC (rev 9462)
@@ -53,6 +53,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/conf.h>
#include <sys/eventhandler.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
@@ -79,19 +80,18 @@
#include <dev/dpt/dpt.h>
/* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */
-int dpt_controllers_present;
devclass_t dpt_devclass;
#define microtime_now dpt_time_now()
#define dpt_inl(dpt, port) \
- bus_space_read_4((dpt)->tag, (dpt)->bsh, port)
+ bus_read_4((dpt)->io_res, (dpt)->io_offset + port)
#define dpt_inb(dpt, port) \
- bus_space_read_1((dpt)->tag, (dpt)->bsh, port)
+ bus_read_1((dpt)->io_res, (dpt)->io_offset + port)
#define dpt_outl(dpt, port, value) \
- bus_space_write_4((dpt)->tag, (dpt)->bsh, port, value)
+ bus_write_4((dpt)->io_res, (dpt)->io_offset + port, value)
#define dpt_outb(dpt, port, value) \
- bus_space_write_1((dpt)->tag, (dpt)->bsh, port, value)
+ bus_write_1((dpt)->io_res, (dpt)->io_offset + port, value)
/*
* These will have to be setup by parameters passed at boot/load time. For
@@ -142,6 +142,7 @@
u_int8_t *buff);
static void dpt_poll(struct cam_sim *sim);
+static void dpt_intr_locked(dpt_softc_t *dpt);
static void dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs,
int nseg, int error);
@@ -222,9 +223,9 @@
dptgetccb(struct dpt_softc *dpt)
{
struct dpt_ccb* dccb;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&dpt->lock, MA_OWNED);
if ((dccb = SLIST_FIRST(&dpt->free_dccb_list)) != NULL) {
SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
dpt->free_dccbs--;
@@ -232,13 +233,12 @@
dptallocccbs(dpt);
dccb = SLIST_FIRST(&dpt->free_dccb_list);
if (dccb == NULL)
- printf("dpt%d: Can't malloc DCCB\n", dpt->unit);
+ device_printf(dpt->dev, "Can't malloc DCCB\n");
else {
SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
dpt->free_dccbs--;
}
}
- splx(s);
return (dccb);
}
@@ -246,9 +246,9 @@
static __inline void
dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb)
{
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&dpt->lock, MA_OWNED);
if ((dccb->state & DCCB_ACTIVE) != 0)
LIST_REMOVE(&dccb->ccb->ccb_h, sim_links.le);
if ((dccb->state & DCCB_RELEASE_SIMQ) != 0)
@@ -261,7 +261,6 @@
dccb->state = DCCB_FREE;
SLIST_INSERT_HEAD(&dpt->free_dccb_list, dccb, links);
++dpt->free_dccbs;
- splx(s);
}
static __inline bus_addr_t
@@ -332,7 +331,6 @@
/*
* Allocate another chunk of CCB's. Return count of entries added.
- * Assumed to be called at splcam().
*/
static int
dptallocccbs(dpt_softc_t *dpt)
@@ -344,6 +342,8 @@
int newcount;
int i;
+ if (!dumping)
+ mtx_assert(&dpt->lock, MA_OWNED);
next_ccb = &dpt->dpt_dccbs[dpt->total_dccbs];
if (next_ccb == dpt->dpt_dccbs) {
@@ -371,6 +371,7 @@
&next_ccb->dmamap);
if (error != 0)
break;
+ callout_init_mtx(&next_ccb->timer, &dpt->lock, 0);
next_ccb->sg_list = segs;
next_ccb->sg_busaddr = htonl(physaddr);
next_ccb->eata_ccb.cp_dataDMA = htonl(physaddr);
@@ -404,7 +405,7 @@
*/
if (!conf) {
conf = (dpt_conf_t *)malloc(sizeof(dpt_conf_t),
- M_DEVBUF, M_NOWAIT);
+ M_DEVBUF, M_NOWAIT | M_ZERO);
}
/*
@@ -416,11 +417,6 @@
}
/*
- * If we have one, clean it up.
- */
- bzero(conf, sizeof(dpt_conf_t));
-
- /*
* Reset the controller.
*/
outb((base + HA_WCOMMAND), EATA_CMD_RESET);
@@ -498,9 +494,9 @@
u_int8_t status;
int ndx;
- int ospl;
int result;
+ mtx_assert(&dpt->lock, MA_OWNED);
cp = &dccb->eata_ccb;
bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(*dpt->sp));
@@ -523,8 +519,6 @@
cp->cp_identify = 1;
cp->cp_datalen = htonl(size);
- ospl = splcam();
-
/*
* This could be a simple for loop, but we suspected the compiler To
* have optimized it a bit too much. Wait for the controller to
@@ -540,9 +534,8 @@
* the DPT controller is in a NON PC (PCI?) platform).
*/
if (dpt_raid_busy(dpt)) {
- printf("dpt%d WARNING: Get_conf() RSUS failed.\n",
- dpt->unit);
- splx(ospl);
+ device_printf(dpt->dev,
+ "WARNING: Get_conf() RSUS failed.\n");
return (0);
}
}
@@ -557,10 +550,10 @@
if ((result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
EATA_CMD_DMA_SEND_CP,
10000, 0, 0, 0)) != 0) {
- printf("dpt%d WARNING: Get_conf() failed (%d) to send "
+ device_printf(dpt->dev,
+ "WARNING: Get_conf() failed (%d) to send "
"EATA_CMD_DMA_READ_CONFIG\n",
- dpt->unit, result);
- splx(ospl);
+ result);
return (0);
}
/* Wait for two seconds for a response. This can be slow */
@@ -574,8 +567,6 @@
/* Grab the status and clear interrupts */
status = dpt_inb(dpt, HA_RSTATUS);
- splx(ospl);
-
/*
* Check the status carefully. Return only if the
* command was successful.
@@ -601,10 +592,11 @@
u_int8_t *param;
int bytes;
int result;
- int ospl;
int ndx;
u_int8_t status;
+ mtx_assert(&dpt->lock, MA_OWNED);
+
/*
* Default setting, for best perfromance..
* This is what virtually all cards default to..
@@ -646,14 +638,13 @@
cp->cp_datalen = htonl(512);
- ospl = splcam();
result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
EATA_CMD_DMA_SEND_CP,
10000, 0, 0, 0);
if (result != 0) {
- printf("dpt%d WARNING: detect_cache() failed (%d) to send "
- "EATA_CMD_DMA_SEND_CP\n", dpt->unit, result);
- splx(ospl);
+ device_printf(dpt->dev,
+ "WARNING: detect_cache() failed (%d) to send "
+ "EATA_CMD_DMA_SEND_CP\n", result);
return;
}
/* Wait for two seconds for a response. This can be slow... */
@@ -666,7 +657,6 @@
/* Grab the status and clear interrupts */
status = dpt_inb(dpt, HA_RSTATUS);
- splx(ospl);
/*
* Sanity check
@@ -681,8 +671,7 @@
/*
* DPT Log Page layout error
*/
- printf("dpt%d: NOTICE: Log Page (1) layout error\n",
- dpt->unit);
+ device_printf(dpt->dev, "NOTICE: Log Page (1) layout error\n");
return;
}
if (!(param[4] & 0x4)) {
@@ -721,7 +710,7 @@
static void
dpt_poll(struct cam_sim *sim)
{
- dpt_intr(cam_sim_softc(sim));
+ dpt_intr_locked(cam_sim_softc(sim));
}
static void
@@ -730,16 +719,18 @@
struct dpt_ccb *dccb;
union ccb *ccb;
struct dpt_softc *dpt;
- int s;
dccb = (struct dpt_ccb *)arg;
ccb = dccb->ccb;
dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
+ if (!dumping)
+ mtx_assert(&dpt->lock, MA_OWNED);
if (error != 0) {
if (error != EFBIG)
- printf("dpt%d: Unexepected error 0x%x returned from "
- "bus_dmamap_load\n", dpt->unit, error);
+ device_printf(dpt->dev,
+ "Unexepected error 0x%x returned from "
+ "bus_dmamap_load\n", error);
if (ccb->ccb_h.status == CAM_REQ_INPROG) {
xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
@@ -787,8 +778,6 @@
dccb->eata_ccb.cp_datalen = 0;
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -798,7 +787,6 @@
bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
dptfreeccb(dpt, dccb);
xpt_done(ccb);
- splx(s);
return;
}
@@ -805,9 +793,8 @@
dccb->state |= DCCB_ACTIVE;
ccb->ccb_h.status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le);
- ccb->ccb_h.timeout_ch =
- timeout(dpttimeout, (caddr_t)dccb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&dccb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+ dpttimeout, dccb);
if (dpt_send_eata_command(dpt, &dccb->eata_ccb,
dccb->eata_ccb.cp_busaddr,
EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) {
@@ -817,8 +804,6 @@
dptfreeccb(dpt, dccb);
xpt_done(ccb);
}
-
- splx(s);
}
static void
@@ -829,6 +814,7 @@
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("dpt_action\n"));
dpt = (struct dpt_softc *)cam_sim_softc(sim);
+ mtx_assert(&dpt->lock, MA_OWNED);
if ((dpt->state & DPT_HA_SHUTDOWN_ACTIVE) != 0) {
xpt_print_path(ccb->ccb_h.path);
@@ -856,11 +842,7 @@
return;
}
if ((dccb = dptgetccb(dpt)) == NULL) {
- int s;
-
- s = splcam();
dpt->resource_shortage = 1;
- splx(s);
xpt_freeze_simq(sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@@ -934,10 +916,8 @@
* to a single buffer.
*/
if ((ccbh->flags & CAM_DATA_PHYS) == 0) {
- int s;
int error;
- s = splsoftvm();
error =
bus_dmamap_load(dpt->buffer_dmat,
dccb->dmamap,
@@ -955,7 +935,6 @@
xpt_freeze_simq(sim, 1);
dccb->state |= CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -1106,7 +1085,6 @@
* This routine will try to send an EATA command to the DPT HBA.
* It will, by default, try 20,000 times, waiting 50us between tries.
* It returns 0 on success and 1 on failure.
- * It is assumed to be called at splcam().
*/
static int
dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block,
@@ -1184,9 +1162,7 @@
dpt_softc_t *dpt = device_get_softc(dev);
int i;
- dpt->tag = rman_get_bustag(dpt->io_res);
- dpt->bsh = rman_get_bushandle(dpt->io_res) + dpt->io_offset;
- dpt->unit = device_get_unit(dev);
+ mtx_init(&dpt->lock, "dpt", NULL, MTX_DEF);
SLIST_INIT(&dpt->free_dccb_list);
LIST_INIT(&dpt->pending_ccb_list);
for (i = 0; i < MAX_CHANNELS; i++)
@@ -1230,6 +1206,7 @@
case 0:
break;
}
+ mtx_destroy(&dpt->lock);
}
int
@@ -1302,9 +1279,10 @@
dpt->init_level = 0;
SLIST_INIT(&dpt->sg_maps);
+ mtx_lock(&dpt->lock);
#ifdef DPT_RESET_BOARD
- printf("dpt%d: resetting HBA\n", dpt->unit);
+ device_printf(dpt->dev, "resetting HBA\n");
dpt_outb(dpt, HA_WCOMMAND, EATA_CMD_RESET);
DELAY(750000);
/* XXX Shouldn't we poll a status register or something??? */
@@ -1321,8 +1299,8 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&dpt->sg_dmat) != 0) {
goto error_exit;
}
@@ -1358,8 +1336,8 @@
sizeof(conf), 0xc1, 7, 1);
if (retval != 0) {
- printf("dpt%d: Failed to get board configuration\n", dpt->unit);
- return (retval);
+ device_printf(dpt->dev, "Failed to get board configuration\n");
+ goto error_exit;
}
bcopy(&dccb[1], &conf, sizeof(conf));
@@ -1367,8 +1345,8 @@
retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
sizeof(dpt->board_data), 0, conf.scsi_id0, 0);
if (retval != 0) {
- printf("dpt%d: Failed to get inquiry information\n", dpt->unit);
- return (retval);
+ device_printf(dpt->dev, "Failed to get inquiry information\n");
+ goto error_exit;
}
bcopy(&dccb[1], &dpt->board_data, sizeof(dpt->board_data));
@@ -1417,8 +1395,8 @@
dpt->max_dccbs = ntohs(conf.queuesiz);
if (dpt->max_dccbs > 256) {
- printf("dpt%d: Max CCBs reduced from %d to "
- "256 due to tag algorithm\n", dpt->unit, dpt->max_dccbs);
+ device_printf(dpt->dev, "Max CCBs reduced from %d to "
+ "256 due to tag algorithm\n", dpt->max_dccbs);
dpt->max_dccbs = 256;
}
@@ -1451,9 +1429,10 @@
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &dpt->lock,
&dpt->buffer_dmat) != 0) {
- printf("dpt: bus_dma_tag_create(...,dpt->buffer_dmat) failed\n");
+ device_printf(dpt->dev,
+ "bus_dma_tag_create(...,dpt->buffer_dmat) failed\n");
goto error_exit;
}
@@ -1473,10 +1452,11 @@
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&dpt->dccb_dmat) != 0) {
- printf("dpt: bus_dma_tag_create(...,dpt->dccb_dmat) failed\n");
+ device_printf(dpt->dev,
+ "bus_dma_tag_create(...,dpt->dccb_dmat) failed\n");
goto error_exit;
}
@@ -1485,7 +1465,8 @@
/* Allocation for our ccbs and interrupt status packet */
if (bus_dmamem_alloc(dpt->dccb_dmat, (void **)&dpt->dpt_dccbs,
BUS_DMA_NOWAIT, &dpt->dccb_dmamap) != 0) {
- printf("dpt: bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n");
+ device_printf(dpt->dev,
+ "bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n");
goto error_exit;
}
@@ -1511,7 +1492,8 @@
/* Allocate our first batch of ccbs */
if (dptallocccbs(dpt) == 0) {
- printf("dpt: dptallocccbs(dpt) == 0\n");
+ device_printf(dpt->dev, "dptallocccbs(dpt) == 0\n");
+ mtx_unlock(&dpt->lock);
return (2);
}
@@ -1527,8 +1509,8 @@
strp += string_sizes[i];
}
- printf("dpt%d: %.8s %.16s FW Rev. %.4s, ",
- dpt->unit, dpt->board_data.vendor,
+ device_printf(dpt->dev, "%.8s %.16s FW Rev. %.4s, ",
+ dpt->board_data.vendor,
dpt->board_data.modelNum, dpt->board_data.firmware);
printf("%d channel%s, ", dpt->channels, dpt->channels > 1 ? "s" : "");
@@ -1541,9 +1523,11 @@
}
printf("%d CCBs\n", dpt->max_dccbs);
+ mtx_unlock(&dpt->lock);
return (0);
error_exit:
+ mtx_unlock(&dpt->lock);
return (1);
}
@@ -1560,12 +1544,13 @@
if (devq == NULL)
return (0);
+ mtx_lock(&dpt->lock);
for (i = 0; i < dpt->channels; i++) {
/*
* Construct our SIM entry
*/
dpt->sims[i] = cam_sim_alloc(dpt_action, dpt_poll, "dpt",
- dpt, dpt->unit, &Giant,
+ dpt, device_get_unit(dpt->dev), &dpt->lock,
/*untagged*/2,
/*tagged*/dpt->max_dccbs, devq);
if (dpt->sims[i] == NULL) {
@@ -1595,6 +1580,7 @@
}
}
+ mtx_unlock(&dpt->lock);
if (i > 0)
EVENTHANDLER_REGISTER(shutdown_final, dptshutdown,
dpt, SHUTDOWN_PRI_DEFAULT);
@@ -1609,6 +1595,7 @@
dpt = device_get_softc(dev);
+ mtx_lock(&dpt->lock);
for (i = 0; i < dpt->channels; i++) {
#if 0
xpt_async(AC_LOST_DEVICE, dpt->paths[i], NULL);
@@ -1617,6 +1604,7 @@
xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
cam_sim_free(dpt->sims[i], /*free_devq*/TRUE);
}
+ mtx_unlock(&dpt->lock);
dptshutdown((void *)dpt, SHUTDOWN_PRI_DEFAULT);
@@ -1634,6 +1622,16 @@
dpt_intr(void *arg)
{
dpt_softc_t *dpt;
+
+ dpt = arg;
+ mtx_lock(&dpt->lock);
+ dpt_intr_locked(dpt);
+ mtx_unlock(&dpt->lock);
+}
+
+void
+dpt_intr_locked(dpt_softc_t *dpt)
+{
dpt_ccb_t *dccb;
union ccb *ccb;
u_int status;
@@ -1642,8 +1640,6 @@
u_int scsi_stat;
u_int32_t residue_len; /* Number of bytes not transferred */
- dpt = (dpt_softc_t *)arg;
-
/* First order of business is to check if this interrupt is for us */
while (((aux_status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ) != 0) {
@@ -1654,7 +1650,8 @@
*/
if (dpt->sp->ccb_busaddr < dpt->dpt_ccb_busbase
|| dpt->sp->ccb_busaddr >= dpt->dpt_ccb_busend) {
- printf("Encountered bogus status packet\n");
+ device_printf(dpt->dev,
+ "Encountered bogus status packet\n");
status = dpt_inb(dpt, HA_RSTATUS);
return;
}
@@ -1665,9 +1662,10 @@
/* Ignore status packets with EOC not set */
if (dpt->sp->EOC == 0) {
- printf("dpt%d ERROR: Request %d received with "
+ device_printf(dpt->dev,
+ "ERROR: Request %d received with "
"clear EOC.\n Marking as LOST.\n",
- dpt->unit, dccb->transaction_id);
+ dccb->transaction_id);
#ifdef DPT_HANDLE_TIMEOUTS
dccb->state |= DPT_CCB_STATE_MARKED_LOST;
@@ -1697,13 +1695,13 @@
/* Check that this is not a board reset interrupt */
if (dpt_just_reset(dpt)) {
- printf("dpt%d: HBA rebooted.\n"
+ device_printf(dpt->dev, "HBA rebooted.\n"
" All transactions should be "
- "resubmitted\n",
- dpt->unit);
+ "resubmitted\n");
- printf("dpt%d: >>---->> This is incomplete, "
- "fix me.... <<----<<", dpt->unit);
+ device_printf(dpt->dev,
+ ">>---->> This is incomplete, "
+ "fix me.... <<----<<");
panic("DPT Rebooted");
}
@@ -1710,7 +1708,7 @@
}
/* Process CCB */
ccb = dccb->ccb;
- untimeout(dpttimeout, dccb, ccb->ccb_h.timeout_ch);
+ callout_stop(&dccb->timer);
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
bus_dmasync_op_t op;
@@ -1804,7 +1802,7 @@
ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
break;
default:
- printf("dpt%d: Undocumented Error %x\n", dpt->unit, hba_stat);
+ device_printf(dpt->dev, "Undocumented Error %x\n", hba_stat);
printf("Please mail this message to shimon at simon-shapiro.org\n");
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
break;
@@ -1819,16 +1817,14 @@
struct dpt_ccb *dccb;
union ccb *ccb;
struct dpt_softc *dpt;
- int s;
dccb = (struct dpt_ccb *)arg;
ccb = dccb->ccb;
dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
+ mtx_assert(&dpt->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out\n", (void *)dccb);
- s = splcam();
-
/*
* Try to clear any pending jobs. FreeBSD will lose interrupts,
* leaving the controller suspended, and commands timed-out.
@@ -1835,13 +1831,12 @@
* By calling the interrupt handler, any command thus stuck will be
* completed.
*/
- dpt_intr(dpt);
+ dpt_intr_locked(dpt);
if ((dccb->state & DCCB_ACTIVE) == 0) {
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out CCB already completed\n",
(void *)dccb);
- splx(s);
return;
}
@@ -1849,7 +1844,6 @@
dpt_send_immediate(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr,
/*retries*/20000, EATA_SPECIFIC_ABORT, 0, 0);
ccb->ccb_h.status = CAM_CMD_TIMEOUT;
- splx(s);
}
/*
@@ -1863,16 +1857,18 @@
dpt = (dpt_softc_t *)arg;
- printf("dpt%d: Shutting down (mode %x) HBA. Please wait...\n",
- dpt->unit, howto);
+ device_printf(dpt->dev,
+ "Shutting down (mode %x) HBA. Please wait...\n", howto);
/*
* What we do for a shutdown, is give the DPT early power loss warning
*/
+ mtx_lock(&dpt->lock);
dpt_send_immediate(dpt, NULL, 0, EATA_POWER_OFF_WARN, 0, 0, 0);
+ mtx_unlock(&dpt->lock);
DELAY(1000 * 1000 * 5);
- printf("dpt%d: Controller was warned of shutdown and is now "
- "disabled\n", dpt->unit);
+ device_printf(dpt->dev, "Controller was warned of shutdown and is now "
+ "disabled\n");
}
/*============================================================================*/
@@ -1891,11 +1887,12 @@
dpt_reset_hba(dpt_softc_t *dpt)
{
eata_ccb_t *ccb;
- int ospl;
dpt_ccb_t dccb, *dccbp;
int result;
struct scsi_xfer *xs;
-
+
+ mtx_assert(&dpt->lock, MA_OWNED);
+
/* Prepare a control block. The SCSI command part is immaterial */
dccb.xs = NULL;
dccb.flags = 0;
@@ -1921,26 +1918,24 @@
ccb->cp_scsi_cmd = 0; /* Should be ignored */
/* Lock up the submitted queue. We are very persistant here */
- ospl = splcam();
while (dpt->queue_status & DPT_SUBMITTED_QUEUE_ACTIVE) {
DELAY(100);
}
dpt->queue_status |= DPT_SUBMITTED_QUEUE_ACTIVE;
- splx(ospl);
/* Send the RESET message */
if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
EATA_CMD_RESET, 0, 0, 0, 0)) != 0) {
- printf("dpt%d: Failed to send the RESET message.\n"
- " Trying cold boot (ouch!)\n", dpt->unit);
+ device_printf(dpt->dev, "Failed to send the RESET message.\n"
+ " Trying cold boot (ouch!)\n");
if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
EATA_COLD_BOOT, 0, 0,
0, 0)) != 0) {
- panic("dpt%d: Faild to cold boot the HBA\n",
- dpt->unit);
+ panic("%s: Faild to cold boot the HBA\n",
+ device_get_nameunit(dpt->dev));
}
#ifdef DPT_MEASURE_PERFORMANCE
dpt->performance.cold_boots++;
@@ -1951,8 +1946,8 @@
dpt->performance.warm_starts++;
#endif /* DPT_MEASURE_PERFORMANCE */
- printf("dpt%d: Aborting pending requests. O/S should re-submit\n",
- dpt->unit);
+ device_printf(dpt->dev,
+ "Aborting pending requests. O/S should re-submit\n");
while ((dccbp = TAILQ_FIRST(&dpt->completed_ccbs)) != NULL) {
struct scsi_xfer *xs = dccbp->xs;
@@ -1972,13 +1967,11 @@
(dccbp->std_callback)(dpt, dccbp->eata_ccb.cp_channel,
dccbp);
} else {
- ospl = splcam();
dpt_Qpush_free(dpt, dccbp);
- splx(ospl);
}
}
- printf("dpt%d: reset done aborting all pending commands\n", dpt->unit);
+ device_printf(dpt->dev, "reset done aborting all pending commands\n");
dpt->queue_status &= ~DPT_SUBMITTED_QUEUE_ACTIVE;
}
@@ -2000,11 +1993,12 @@
u_int16_t length, u_int16_t offset)
{
eata_ccb_t *cp;
- int ospl;
+ mtx_assert(&dpt->lock, MA_OWNED);
if ((length + offset) > DPT_MAX_TARGET_MODE_BUFFER_SIZE) {
- printf("dpt%d: Length of %d, and offset of %d are wrong\n",
- dpt->unit, length, offset);
+ device_printf(dpt->dev,
+ "Length of %d, and offset of %d are wrong\n",
+ length, offset);
length = DPT_MAX_TARGET_MODE_BUFFER_SIZE;
offset = 0;
}
@@ -2048,8 +2042,8 @@
*/
if (dpt_scatter_gather(dpt, ccb, DPT_RW_BUFFER_SIZE,
dpt->rw_buffer[bus][target][lun])) {
- printf("dpt%d: Failed to setup Scatter/Gather for "
- "Target-Mode buffer\n", dpt->unit);
+ device_printf(dpt->dev, "Failed to setup Scatter/Gather for "
+ "Target-Mode buffer\n");
}
}
@@ -2060,11 +2054,9 @@
u_int8_t bus, u_int8_t target, u_int8_t lun, int mode,
u_int16_t length, u_int16_t offset, dpt_ccb_t * ccb)
{
- int ospl;
+ mtx_assert(&dpt->lock, MA_OWNED);
if (dpt->target_mode_enabled) {
- ospl = splcam();
-
if (!redo)
dpt_target_ccb(dpt, bus, target, lun, ccb, mode,
SCSI_TM_READ_BUFFER, length, offset);
@@ -2077,11 +2069,9 @@
#endif
dpt_Qadd_waiting(dpt, ccb);
dpt_sched_queue(dpt);
-
- splx(ospl);
} else {
- printf("dpt%d: Target Mode Request, but Target Mode is OFF\n",
- dpt->unit);
+ device_printf(dpt->dev,
+ "Target Mode Request, but Target Mode is OFF\n");
}
}
@@ -2101,44 +2091,39 @@
{
dpt_softc_t *dpt;
dpt_ccb_t *ccb = NULL;
- int ospl;
/* This is an external call. Be a bit paranoid */
- for (dpt = TAILQ_FIRST(&dpt_softc_list);
- dpt != NULL;
- dpt = TAILQ_NEXT(dpt, links)) {
- if (dpt->unit == unit)
- goto valid_unit;
- }
+ dpt = devclass_get_device(dpt_devclass, unit);
+ if (dpt == NULL)
+ return (INVALID_UNIT);
- return (INVALID_UNIT);
-
-valid_unit:
-
+ mtx_lock(&dpt->lock);
if (dpt->target_mode_enabled) {
if ((channel >= dpt->channels) || (target > dpt->max_id) ||
(lun > dpt->max_lun)) {
+ mtx_unlock(&dpt->lock);
return (INVALID_SENDER);
}
if ((dpt->rw_buffer[channel][target][lun] == NULL) ||
- (dpt->buffer_receiver[channel][target][lun] == NULL))
+ (dpt->buffer_receiver[channel][target][lun] == NULL)) {
+ mtx_unlock(&dpt->lock);
return (NOT_REGISTERED);
+ }
- ospl = splsoftcam();
/* Process the free list */
if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
- printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n"
- " Please try later\n",
- dpt->unit);
- splx(ospl);
+ device_printf(dpt->dev,
+ "ERROR: Cannot allocate any more free CCB's.\n"
+ " Please try later\n");
+ mtx_unlock(&dpt->lock);
return (NO_RESOURCES);
}
/* Now grab the newest CCB */
if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
- splx(ospl);
- panic("dpt%d: Got a NULL CCB from pop_free()\n", dpt->unit);
+ mtx_unlock(&dpt->lock);
+ panic("%s: Got a NULL CCB from pop_free()\n",
+ device_get_nameunit(dpt->dev));
}
- splx(ospl);
bcopy(dpt->rw_buffer[channel][target][lun] + offset, data, length);
dpt_target_ccb(dpt, channel, target, lun, ccb, mode,
@@ -2146,7 +2131,6 @@
length, offset);
ccb->std_callback = (ccb_callback) callback; /* Potential trouble */
- ospl = splcam();
ccb->transaction_id = ++dpt->commands_processed;
#ifdef DPT_MEASURE_PERFORMANCE
@@ -2156,9 +2140,10 @@
dpt_Qadd_waiting(dpt, ccb);
dpt_sched_queue(dpt);
- splx(ospl);
+ mtx_unlock(&dpt->lock);
return (0);
}
+ mtx_unlock(&dpt->lock);
return (DRIVER_DOWN);
}
@@ -2165,7 +2150,6 @@
static void
dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
{
- int ospl;
eata_ccb_t *cp;
cp = &ccb->eata_ccb;
@@ -2175,9 +2159,7 @@
* We do NOT put it back on the free, etc., queues as it is a special
* ccb, owned by the dpt_softc of this unit.
*/
- ospl = splsoftcam();
dpt_Qremove_completed(dpt, ccb);
- splx(ospl);
#define br_channel (ccb->eata_ccb.cp_channel)
#define br_target (ccb->eata_ccb.cp_id)
@@ -2194,8 +2176,8 @@
case SCSI_TM_READ_BUFFER:
if (read_buffer_callback != NULL) {
/* This is a buffer generated by a kernel process */
- read_buffer_callback(dpt->unit, br_channel,
- br_target, br_lun,
+ read_buffer_callback(device_get_unit(dpt->dev),
+ br_channel, br_target, br_lun,
read_buffer,
br_offset, br_length);
} else {
@@ -2211,18 +2193,17 @@
break;
case SCSI_TM_WRITE_BUFFER:
- (ccb->wrbuff_callback) (dpt->unit, br_channel, br_target,
- br_offset, br_length,
+ (ccb->wrbuff_callback) (device_get_unit(dpt->dev), br_channel,
+ br_target, br_offset, br_length,
br_lun, ccb->status_packet.hba_stat);
break;
default:
- printf("dpt%d: %s is an unsupported command for target mode\n",
- dpt->unit, scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd));
+ device_printf(dpt->dev,
+ "%s is an unsupported command for target mode\n",
+ scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd));
}
- ospl = splsoftcam();
dpt->target_ccb[br_channel][br_target][br_lun] = NULL;
dpt_Qpush_free(dpt, ccb);
- splx(ospl);
}
@@ -2240,23 +2221,21 @@
dpt_ccb_t *ccb = NULL;
int ospl;
- for (dpt = TAILQ_FIRST(&dpt_softc_list);
- dpt != NULL;
- dpt = TAILQ_NEXT(dpt, links)) {
- if (dpt->unit == unit)
- goto valid_unit;
- }
+ dpt = devclass_get_device(dpt_devclass, unit);
+ if (dpt == NULL)
+ return (INVALID_UNIT);
+ mtx_lock(&dpt->lock);
- return (INVALID_UNIT);
-
-valid_unit:
-
- if (dpt->state & DPT_HA_SHUTDOWN_ACTIVE)
+ if (dpt->state & DPT_HA_SHUTDOWN_ACTIVE) {
+ mtx_unlock(&dpt->lock);
return (DRIVER_DOWN);
+ }
if ((channel > (dpt->channels - 1)) || (target > (dpt->max_id - 1)) ||
- (lun > (dpt->max_lun - 1)))
+ (lun > (dpt->max_lun - 1))) {
+ mtx_unlock(&dpt->lock);
return (INVALID_SENDER);
+ }
if (dpt->buffer_receiver[channel][target][lun] == NULL) {
if (op == REGISTER_BUFFER) {
@@ -2263,23 +2242,21 @@
/* Assign the requested callback */
dpt->buffer_receiver[channel][target][lun] = callback;
/* Get a CCB */
- ospl = splsoftcam();
/* Process the free list */
if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
- printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n"
- " Please try later\n",
- dpt->unit);
- splx(ospl);
+ device_printf(dpt->dev,
+ "ERROR: Cannot allocate any more free CCB's.\n"
+ " Please try later\n");
+ mtx_unlock(&dpt->lock);
return (NO_RESOURCES);
}
/* Now grab the newest CCB */
if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
- splx(ospl);
- panic("dpt%d: Got a NULL CCB from pop_free()\n",
- dpt->unit);
+ mtx_unlock(&dpt->lock);
+ panic("%s: Got a NULL CCB from pop_free()\n",
+ device_get_nameunit(dpt->dev));
}
- splx(ospl);
/* Clean up the leftover of the previous tenant */
ccb->status = DPT_CCB_STATE_NEW;
@@ -2288,37 +2265,44 @@
dpt->rw_buffer[channel][target][lun] =
malloc(DPT_RW_BUFFER_SIZE, M_DEVBUF, M_NOWAIT);
if (dpt->rw_buffer[channel][target][lun] == NULL) {
- printf("dpt%d: Failed to allocate "
- "Target-Mode buffer\n", dpt->unit);
- ospl = splsoftcam();
+ device_printf(dpt->dev, "Failed to allocate "
+ "Target-Mode buffer\n");
dpt_Qpush_free(dpt, ccb);
- splx(ospl);
+ mtx_unlock(&dpt->lock);
return (NO_RESOURCES);
}
dpt_set_target(0, dpt, channel, target, lun, mode,
length, offset, ccb);
+ mtx_unlock(&dpt->lock);
return (SUCCESSFULLY_REGISTERED);
- } else
+ } else {
+ mtx_unlock(&dpt->lock);
return (NOT_REGISTERED);
+ }
} else {
if (op == REGISTER_BUFFER) {
- if (dpt->buffer_receiver[channel][target][lun] == callback)
+ if (dpt->buffer_receiver[channel][target][lun] == callback) {
+ mtx_unlock(&dpt->lock);
return (ALREADY_REGISTERED);
- else
+ } else {
+ mtx_unlock(&dpt->lock);
return (REGISTERED_TO_ANOTHER);
+ }
} else {
if (dpt->buffer_receiver[channel][target][lun] == callback) {
dpt->buffer_receiver[channel][target][lun] = NULL;
- ospl = splsoftcam();
dpt_Qpush_free(dpt, ccb);
- splx(ospl);
free(dpt->rw_buffer[channel][target][lun], M_DEVBUF);
+ mtx_unlock(&dpt->lock);
return (SUCCESSFULLY_REGISTERED);
- } else
+ } else {
+ mtx_unlock(&dpt->lock);
return (INVALID_CALLBACK);
+ }
}
}
+ mtx_unlock(&dpt->lock);
}
/* Return the state of the blinking DPT LED's */
@@ -2326,13 +2310,11 @@
dpt_blinking_led(dpt_softc_t * dpt)
{
int ndx;
- int ospl;
u_int32_t state;
u_int32_t previous;
u_int8_t result;
- ospl = splcam();
-
+ mtx_assert(&dpt->lock, MA_OWNED);
result = 0;
for (ndx = 0, state = 0, previous = 0;
@@ -2345,7 +2327,6 @@
if ((state == previous) && (state == DPT_BLINK_INDICATOR))
result = dpt_inb(dpt, 5);
- splx(ospl);
return (result);
}
@@ -2363,9 +2344,9 @@
int channel, target, lun;
int huh;
int result;
- int ospl;
int submitted;
+ mtx_assert(&dpt->lock, MA_OWNED);
data = NULL;
channel = minor2hba(minor_no);
target = minor2target(minor_no);
@@ -2386,22 +2367,19 @@
}
}
/* Get a DPT CCB, so we can prepare a command */
- ospl = splsoftcam();
/* Process the free list */
if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
- printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n"
- " Please try later\n",
- dpt->unit);
- splx(ospl);
+ device_printf(dpt->dev,
+ "ERROR: Cannot allocate any more free CCB's.\n"
+ " Please try later\n");
return (EFAULT);
}
/* Now grab the newest CCB */
if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
- splx(ospl);
- panic("dpt%d: Got a NULL CCB from pop_free()\n", dpt->unit);
+ panic("%s: Got a NULL CCB from pop_free()\n",
+ device_get_nameunit(dpt->dev));
} else {
- splx(ospl);
/* Clean up the leftover of the previous tenant */
ccb->status = DPT_CCB_STATE_NEW;
}
@@ -2434,8 +2412,8 @@
}
if (data == NULL) {
- printf("dpt%d: Cannot allocate %d bytes "
- "for EATA command\n", dpt->unit,
+ device_printf(dpt->dev, "Cannot allocate %d bytes "
+ "for EATA command\n",
ccb->eata_ccb.cp_datalen);
return (EFAULT);
}
@@ -2471,13 +2449,11 @@
if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD)
&& (ccb->eata_ccb.cp_cdb[2] == BUS_QUIET)) {
/* We wait for ALL traffic for this HBa to subside */
- ospl = splsoftcam();
dpt->state |= DPT_HA_QUIET;
- splx(ospl);
while ((submitted = dpt->submitted_ccbs_count) != 0) {
- huh = tsleep((void *) dpt, PCATCH | PRIBIO, "dptqt",
- 100 * hz);
+ huh = mtx_sleep((void *) dpt, &dpt->lock,
+ PCATCH | PRIBIO, "dptqt", 100 * hz);
switch (huh) {
case 0:
/* Wakeup call received */
@@ -2494,9 +2470,7 @@
/* Resume normal operation */
if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD)
&& (ccb->eata_ccb.cp_cdb[2] == BUS_UNQUIET)) {
- ospl = splsoftcam();
dpt->state &= ~DPT_HA_QUIET;
- splx(ospl);
}
/**
* Schedule the command and submit it.
@@ -2515,14 +2489,13 @@
++dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd];
ccb->command_started = microtime_now;
#endif
- ospl = splcam();
dpt_Qadd_waiting(dpt, ccb);
- splx(ospl);
dpt_sched_queue(dpt);
/* Wait for the command to complete */
- (void) tsleep((void *) ccb, PCATCH | PRIBIO, "dptucw", 100 * hz);
+ (void) mtx_sleep((void *) ccb, &dpt->lock, PCATCH | PRIBIO, "dptucw",
+ 100 * hz);
/* Free allocated memory */
if (data != NULL)
@@ -2534,10 +2507,11 @@
static void
dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
{
- int ospl = splsoftcam();
u_int32_t result;
caddr_t cmd_arg;
+ mtx_unlock(&dpt->lock);
+
/**
* If Auto Request Sense is on, copyout the sense struct
*/
@@ -2546,9 +2520,9 @@
if (ccb->eata_ccb.Auto_Req_Sen == 1) {
if (copyout((caddr_t) & ccb->sense_data, usr_pckt_DMA,
sizeof(struct scsi_sense_data))) {
+ mtx_lock(&dpt->lock);
ccb->result = EFAULT;
dpt_Qpush_free(dpt, ccb);
- splx(ospl);
wakeup(ccb);
return;
}
@@ -2557,10 +2531,10 @@
if ((ccb->eata_ccb.DataIn == 1)
&& (ccb->status_packet.hba_stat == HA_NO_ERROR)) {
if (copyout(ccb->data, usr_pckt_DMA, usr_pckt_len)) {
+ mtx_lock(&dpt->lock);
dpt_Qpush_free(dpt, ccb);
ccb->result = EFAULT;
- splx(ospl);
wakeup(ccb);
return;
}
@@ -2570,18 +2544,18 @@
cmd_arg = (caddr_t) ccb->result;
if (copyout((caddr_t) & result, cmd_arg, sizeof(result))) {
+ mtx_lock(&dpt->lock);
dpt_Qpush_free(dpt, ccb);
ccb->result = EFAULT;
- splx(ospl);
wakeup(ccb);
return;
}
+ mtx_lock(&dpt->lock);
/* Put the CCB back in the freelist */
ccb->state |= DPT_CCB_STATE_COMPLETED;
dpt_Qpush_free(dpt, ccb);
/* Free allocated memory */
- splx(ospl);
return;
}
@@ -2611,22 +2585,15 @@
dpt_handle_timeouts(dpt_softc_t * dpt)
{
dpt_ccb_t *ccb;
- int ospl;
- ospl = splcam();
-
if (dpt->state & DPT_HA_TIMEOUTS_ACTIVE) {
- printf("dpt%d WARNING: Timeout Handling Collision\n",
- dpt->unit);
- splx(ospl);
+ device_printf(dpt->dev, "WARNING: Timeout Handling Collision\n");
return;
}
dpt->state |= DPT_HA_TIMEOUTS_ACTIVE;
/* Loop through the entire submitted queue, looking for lost souls */
- for (ccb = TAILQ_FIRST(&dpt->submitted_ccbs);
- ccb != NULL;
- ccb = TAILQ_NEXT(ccb, links)) {
+ TAILQ_FIRST(ccb, &&dpt->submitted_ccbs, links) {
struct scsi_xfer *xs;
u_int32_t age, max_age;
@@ -2658,13 +2625,14 @@
ccb->state |= DPT_CCB_STATE_ABORTED;
#define cmd_name scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd)
if (ccb->retries++ > DPT_RETRIES) {
- printf("dpt%d ERROR: Destroying stale "
+ device_printf(dpt->dev,
+ "ERROR: Destroying stale "
"%d (%s)\n"
" on "
"c%db%dt%du%d (%d/%d)\n",
- dpt->unit, ccb->transaction_id,
+ ccb->transaction_id,
cmd_name,
- dpt->unit,
+ device_get_unit(dpt->dev),
ccb->eata_ccb.cp_channel,
ccb->eata_ccb.cp_id,
ccb->eata_ccb.cp_LUN, age,
@@ -2682,13 +2650,14 @@
xs->flags |= SCSI_ITSDONE;
scsi_done(xs);
} else {
- printf("dpt%d ERROR: Stale %d (%s) on "
+ device_printf(dpt->dev,
+ "ERROR: Stale %d (%s) on "
"c%db%dt%du%d (%d)\n"
" gets another "
"chance(%d/%d)\n",
- dpt->unit, ccb->transaction_id,
+ ccb->transaction_id,
cmd_name,
- dpt->unit,
+ device_get_unit(dpt->dev),
ccb->eata_ccb.cp_channel,
ccb->eata_ccb.cp_id,
ccb->eata_ccb.cp_LUN,
@@ -2708,12 +2677,14 @@
*/
if (!(ccb->state & DPT_CCB_STATE_MARKED_LOST) &&
(age != ~0) && (age > max_age)) {
- printf("dpt%d ERROR: Marking %d (%s) on "
+ device_printf(dpt->dev,
+ "ERROR: Marking %d (%s) on "
"c%db%dt%du%d \n"
" as late after %dusec\n",
- dpt->unit, ccb->transaction_id,
+ ccb->transaction_id,
cmd_name,
- dpt->unit, ccb->eata_ccb.cp_channel,
+ device_get_unit(dpt->dev),
+ ccb->eata_ccb.cp_channel,
ccb->eata_ccb.cp_id,
ccb->eata_ccb.cp_LUN, age);
ccb->state |= DPT_CCB_STATE_MARKED_LOST;
@@ -2722,7 +2693,6 @@
}
dpt->state &= ~DPT_HA_TIMEOUTS_ACTIVE;
- splx(ospl);
}
static void
@@ -2730,10 +2700,11 @@
{
dpt_softc_t *dpt = (dpt_softc_t *) arg;
+ mtx_assert(&dpt->lock, MA_OWNED);
if (!(dpt->state & DPT_HA_TIMEOUTS_ACTIVE))
dpt_handle_timeouts(dpt);
- timeout(dpt_timeout, (caddr_t) dpt, hz * 10);
+ callout_reset(&dpt->timer, hz * 10, dpt_timeout, dpt);
}
#endif /* DPT_HANDLE_TIMEOUTS */
More information about the Midnightbsd-cvs
mailing list