summaryrefslogtreecommitdiffstats
path: root/sys/dev/dpt/dpt_scsi.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-10-15 16:29:08 +0000
committerjhb <jhb@FreeBSD.org>2012-10-15 16:29:08 +0000
commit1cfcf4363cad81943fcff8c3fa4a7dafb9ee2ce4 (patch)
tree2a6110445d2c98f88fa835c85396cf1555a715ec /sys/dev/dpt/dpt_scsi.c
parentb7ae8b66cecbc88664583fc7dc1b0a15a416f161 (diff)
downloadFreeBSD-src-1cfcf4363cad81943fcff8c3fa4a7dafb9ee2ce4.zip
FreeBSD-src-1cfcf4363cad81943fcff8c3fa4a7dafb9ee2ce4.tar.gz
Add locking to the dpt(4) driver and mark it MPSAFE.
- Use device_printf() and device_get_unit() instead of storing the unit number in the softc. - Remove use of explicit bus space handles and tags. - Remove the global dpt_softcs list and use devclass_get_device() instead. - Use pci_enable_busmaster() rather than frobbing the PCI command register directly. Tested by: no one
Diffstat (limited to 'sys/dev/dpt/dpt_scsi.c')
-rw-r--r--sys/dev/dpt/dpt_scsi.c451
1 files changed, 211 insertions, 240 deletions
diff --git a/sys/dev/dpt/dpt_scsi.c b/sys/dev/dpt/dpt_scsi.c
index 6a7deda..6533dd8 100644
--- a/sys/dev/dpt/dpt_scsi.c
+++ b/sys/dev/dpt/dpt_scsi.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#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 @@ __FBSDID("$FreeBSD$");
#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 @@ static void dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb,
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 @@ static __inline struct dpt_ccb*
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 @@ dptgetccb(struct dpt_softc *dpt)
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 @@ dptgetccb(struct dpt_softc *dpt)
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 @@ dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb)
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 @@ dptallocsgmap(struct dpt_softc *dpt)
/*
* 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 @@ dptallocccbs(dpt_softc_t *dpt)
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 @@ dptallocccbs(dpt_softc_t *dpt)
&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 @@ dpt_pio_get_conf (u_int32_t base)
*/
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 @@ dpt_pio_get_conf (u_int32_t base)
}
/*
- * 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 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
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 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
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 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
* 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 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
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 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
/* 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 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
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 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
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 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
/* Grab the status and clear interrupts */
status = dpt_inb(dpt, HA_RSTATUS);
- splx(ospl);
/*
* Sanity check
@@ -681,8 +671,7 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
/*
* 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 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
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 @@ dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
struct dpt_ccb *dccb;
union ccb *ccb;
struct dpt_softc *dpt;
- int s;
+ if (!dumping)
+ mtx_assert(&dpt->lock, MA_OWNED);
dccb = (struct dpt_ccb *)arg;
ccb = dccb->ccb;
dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
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 @@ dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
dccb->eata_ccb.cp_datalen = 0;
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -798,16 +787,14 @@ dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
dptfreeccb(dpt, dccb);
xpt_done(ccb);
- splx(s);
return;
}
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 @@ dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
dptfreeccb(dpt, dccb);
xpt_done(ccb);
}
-
- splx(s);
}
static void
@@ -829,6 +814,7 @@ dpt_action(struct cam_sim *sim, union ccb *ccb)
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 @@ dpt_action(struct cam_sim *sim, union ccb *ccb)
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 @@ dpt_action(struct cam_sim *sim, union ccb *ccb)
* 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 @@ dpt_action(struct cam_sim *sim, union ccb *ccb)
xpt_freeze_simq(sim, 1);
dccb->state |= CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -1105,7 +1084,6 @@ dpt_action(struct cam_sim *sim, union ccb *ccb)
* 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,
@@ -1183,9 +1161,7 @@ dpt_alloc(device_t dev)
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++)
@@ -1229,6 +1205,7 @@ dpt_free(struct dpt_softc *dpt)
case 0:
break;
}
+ mtx_destroy(&dpt->lock);
}
int
@@ -1301,9 +1278,10 @@ dpt_init(struct dpt_softc *dpt)
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??? */
@@ -1320,8 +1298,8 @@ dpt_init(struct dpt_softc *dpt)
/* 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;
}
@@ -1357,8 +1335,8 @@ dpt_init(struct dpt_softc *dpt)
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));
@@ -1366,8 +1344,8 @@ dpt_init(struct dpt_softc *dpt)
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));
@@ -1416,8 +1394,8 @@ dpt_init(struct dpt_softc *dpt)
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;
}
@@ -1450,9 +1428,10 @@ dpt_init(struct dpt_softc *dpt)
/* 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;
}
@@ -1472,10 +1451,11 @@ dpt_init(struct dpt_softc *dpt)
/* 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;
}
@@ -1484,7 +1464,8 @@ dpt_init(struct dpt_softc *dpt)
/* 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;
}
@@ -1510,7 +1491,8 @@ dpt_init(struct dpt_softc *dpt)
/* 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);
}
@@ -1526,8 +1508,8 @@ dpt_init(struct dpt_softc *dpt)
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" : "");
@@ -1540,9 +1522,11 @@ dpt_init(struct dpt_softc *dpt)
}
printf("%d CCBs\n", dpt->max_dccbs);
+ mtx_unlock(&dpt->lock);
return (0);
error_exit:
+ mtx_unlock(&dpt->lock);
return (1);
}
@@ -1559,12 +1543,13 @@ dpt_attach(dpt_softc_t *dpt)
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) {
@@ -1594,6 +1579,7 @@ dpt_attach(dpt_softc_t *dpt)
}
}
+ mtx_unlock(&dpt->lock);
if (i > 0)
EVENTHANDLER_REGISTER(shutdown_final, dptshutdown,
dpt, SHUTDOWN_PRI_DEFAULT);
@@ -1608,6 +1594,7 @@ dpt_detach (device_t dev)
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);
@@ -1616,6 +1603,7 @@ dpt_detach (device_t dev)
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);
@@ -1633,6 +1621,16 @@ void
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;
@@ -1641,8 +1639,6 @@ dpt_intr(void *arg)
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) {
@@ -1653,7 +1649,8 @@ dpt_intr(void *arg)
*/
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;
}
@@ -1664,9 +1661,10 @@ dpt_intr(void *arg)
/* 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;
@@ -1696,20 +1694,20 @@ dpt_intr(void *arg)
/* 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");
}
}
/* 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;
@@ -1803,7 +1801,7 @@ dptprocesserror(dpt_softc_t *dpt, dpt_ccb_t *dccb, union ccb *ccb,
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@simon-shapiro.org\n");
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
break;
@@ -1818,29 +1816,26 @@ dpttimeout(void *arg)
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.
* 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;
}
@@ -1848,7 +1843,6 @@ dpttimeout(void *arg)
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);
}
/*
@@ -1862,16 +1856,18 @@ dptshutdown(void *arg, int howto)
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");
}
/*============================================================================*/
@@ -1890,11 +1886,12 @@ static void
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;
@@ -1920,26 +1917,24 @@ dpt_reset_hba(dpt_softc_t *dpt)
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++;
@@ -1950,8 +1945,8 @@ dpt_reset_hba(dpt_softc_t *dpt)
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;
@@ -1971,13 +1966,11 @@ dpt_reset_hba(dpt_softc_t *dpt)
(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;
}
@@ -1999,11 +1992,12 @@ dpt_target_ccb(dpt_softc_t * dpt, int bus, u_int8_t target, u_int8_t lun,
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;
}
@@ -2047,8 +2041,8 @@ dpt_target_ccb(dpt_softc_t * dpt, int bus, u_int8_t target, u_int8_t lun,
*/
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");
}
}
@@ -2059,11 +2053,9 @@ dpt_set_target(int redo, dpt_softc_t * dpt,
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);
@@ -2076,11 +2068,9 @@ dpt_set_target(int redo, dpt_softc_t * dpt,
#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");
}
}
@@ -2100,44 +2090,39 @@ dpt_send_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun,
{
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;
- }
-
- return (INVALID_UNIT);
-
-valid_unit:
+ dpt = devclass_get_device(dpt_devclass, unit);
+ if (dpt == NULL)
+ return (INVALID_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,
@@ -2145,7 +2130,6 @@ valid_unit:
length, offset);
ccb->std_callback = (ccb_callback) callback; /* Potential trouble */
- ospl = splcam();
ccb->transaction_id = ++dpt->commands_processed;
#ifdef DPT_MEASURE_PERFORMANCE
@@ -2155,16 +2139,16 @@ valid_unit:
dpt_Qadd_waiting(dpt, ccb);
dpt_sched_queue(dpt);
- splx(ospl);
+ mtx_unlock(&dpt->lock);
return (0);
}
+ mtx_unlock(&dpt->lock);
return (DRIVER_DOWN);
}
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;
@@ -2174,9 +2158,7 @@ dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
* 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)
@@ -2193,8 +2175,8 @@ dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
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 {
@@ -2210,18 +2192,17 @@ dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
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);
}
@@ -2239,46 +2220,42 @@ dpt_register_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun,
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;
- }
-
- return (INVALID_UNIT);
-
-valid_unit:
+ dpt = devclass_get_device(dpt_devclass, unit);
+ if (dpt == NULL)
+ return (INVALID_UNIT);
+ mtx_lock(&dpt->lock);
- 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) {
/* 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;
@@ -2287,37 +2264,44 @@ valid_unit:
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 */
@@ -2325,13 +2309,11 @@ u_int8_t
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;
@@ -2344,7 +2326,6 @@ dpt_blinking_led(dpt_softc_t * dpt)
if ((state == previous) && (state == DPT_BLINK_INDICATOR))
result = dpt_inb(dpt, 5);
- splx(ospl);
return (result);
}
@@ -2362,9 +2343,9 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
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);
@@ -2385,22 +2366,19 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
}
}
/* 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;
}
@@ -2433,8 +2411,8 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
}
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);
}
@@ -2470,13 +2448,11 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
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 */
@@ -2493,9 +2469,7 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
/* 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.
@@ -2514,14 +2488,13 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
++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)
@@ -2533,10 +2506,11 @@ dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
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
*/
@@ -2545,9 +2519,9 @@ dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
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;
}
@@ -2556,10 +2530,10 @@ dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
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;
}
@@ -2569,18 +2543,18 @@ dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
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;
}
@@ -2610,22 +2584,15 @@ static void
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;
@@ -2657,13 +2624,14 @@ dpt_handle_timeouts(dpt_softc_t * dpt)
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,
@@ -2681,13 +2649,14 @@ dpt_handle_timeouts(dpt_softc_t * dpt)
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,
@@ -2707,12 +2676,14 @@ dpt_handle_timeouts(dpt_softc_t * dpt)
*/
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;
@@ -2721,7 +2692,6 @@ dpt_handle_timeouts(dpt_softc_t * dpt)
}
dpt->state &= ~DPT_HA_TIMEOUTS_ACTIVE;
- splx(ospl);
}
static void
@@ -2729,10 +2699,11 @@ dpt_timeout(void *arg)
{
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 */
OpenPOWER on IntegriCloud