aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2008-04-24 22:48:34 +0000
committerMarius Strobl <marius@FreeBSD.org>2008-04-24 22:48:34 +0000
commit82897554f5e88752948491b038357b453068ba2b (patch)
treec9b22bff32de3c305796a17f17f2080f5f61e021 /sys
parent6b0c4e979ec5bb43ded2dab22c49290097ae5898 (diff)
downloadsrc-82897554f5e88752948491b038357b453068ba2b.tar.gz
src-82897554f5e88752948491b038357b453068ba2b.zip
- Use bus_{read,write}_*(9) instead of bus_space_{read,write}_*(9)
in order to get rid of bus space handle and tag in struct sym_hcb. - Remove unused members related to bus addresses in struct sym_hcb. - sym(4) takes care of allocating an instance of struct sym_hcb itself so don't let newbus allocate it as an unused softc also. - Add basic MPSAFE locking. This includes changing the sym(4) CCBs to be allocated up-front instead of on demand as needed. Besides making these allocations more likely to succeed, this also solves the problem of calling bus_dmamap_create(9) with the SIM mutex held. Reviewed by: scottl MFC after: 1 month
Notes
Notes: svn path=/head/; revision=178468
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sym/sym_hipd.c273
1 files changed, 155 insertions, 118 deletions
diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index 8e5b963109d2..b3df7987e9be 100644
--- a/sys/dev/sym/sym_hipd.c
+++ b/sys/dev/sym/sym_hipd.c
@@ -614,7 +614,7 @@ static m_addr_t ___dma_getp(m_pool_s *mp)
goto out_err;
if (bus_dmamem_alloc(mp->dmat, &vaddr,
- BUS_DMA_NOWAIT, &vbp->dmamap))
+ BUS_DMA_COHERENT | BUS_DMA_WAITOK, &vbp->dmamap))
goto out_err;
bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr,
MEMO_CLUSTER_SIZE, getbaddrcb, &baddr, BUS_DMA_NOWAIT);
@@ -680,7 +680,7 @@ static m_pool_s *___cre_dma_pool(bus_dma_tag_t dev_dmat)
BUS_SPACE_MAXADDR,
NULL, NULL, MEMO_CLUSTER_SIZE, 1,
MEMO_CLUSTER_SIZE, 0,
- busdma_lock_mutex, &Giant, &mp->dmat)) {
+ NULL, NULL, &mp->dmat)) {
mp->getp = ___dma_getp;
#ifdef MEMO_FREE_UNUSED
mp->freep = ___dma_freep;
@@ -876,28 +876,28 @@ struct sym_nvram {
#if defined(SYM_CONF_IOMAPPED)
-#define INB_OFF(o) bus_space_read_1(np->io_tag, np->io_bsh, o)
-#define INW_OFF(o) bus_space_read_2(np->io_tag, np->io_bsh, o)
-#define INL_OFF(o) bus_space_read_4(np->io_tag, np->io_bsh, o)
+#define INB_OFF(o) bus_read_1(np->io_res, (o))
+#define INW_OFF(o) bus_read_2(np->io_res, (o))
+#define INL_OFF(o) bus_read_4(np->io_res, (o))
-#define OUTB_OFF(o, v) bus_space_write_1(np->io_tag, np->io_bsh, o, (v))
-#define OUTW_OFF(o, v) bus_space_write_2(np->io_tag, np->io_bsh, o, (v))
-#define OUTL_OFF(o, v) bus_space_write_4(np->io_tag, np->io_bsh, o, (v))
+#define OUTB_OFF(o, v) bus_write_1(np->io_res, (o), (v))
+#define OUTW_OFF(o, v) bus_write_2(np->io_res, (o), (v))
+#define OUTL_OFF(o, v) bus_write_4(np->io_res, (o), (v))
#else /* Memory mapped IO */
-#define INB_OFF(o) bus_space_read_1(np->mmio_tag, np->mmio_bsh, o)
-#define INW_OFF(o) bus_space_read_2(np->mmio_tag, np->mmio_bsh, o)
-#define INL_OFF(o) bus_space_read_4(np->mmio_tag, np->mmio_bsh, o)
+#define INB_OFF(o) bus_read_1(np->mmio_res, (o))
+#define INW_OFF(o) bus_read_2(np->mmio_res, (o))
+#define INL_OFF(o) bus_read_4(np->mmio_res, (o))
-#define OUTB_OFF(o, v) bus_space_write_1(np->mmio_tag, np->mmio_bsh, o, (v))
-#define OUTW_OFF(o, v) bus_space_write_2(np->mmio_tag, np->mmio_bsh, o, (v))
-#define OUTL_OFF(o, v) bus_space_write_4(np->mmio_tag, np->mmio_bsh, o, (v))
+#define OUTB_OFF(o, v) bus_write_1(np->mmio_res, (o), (v))
+#define OUTW_OFF(o, v) bus_write_2(np->mmio_res, (o), (v))
+#define OUTL_OFF(o, v) bus_write_4(np->mmio_res, (o), (v))
#endif /* SYM_CONF_IOMAPPED */
#define OUTRAM_OFF(o, a, l) \
- bus_space_write_region_1(np->ram_tag, np->ram_bsh, o, (a), (l))
+ bus_write_region_1(np->ram_res, (o), (a), (l))
/*
@@ -1033,6 +1033,13 @@ struct sym_nvram {
/*
* Misc.
*/
+#define SYM_LOCK() mtx_lock(&np->mtx)
+#define SYM_LOCK_ASSERT(_what) mtx_assert(&np->mtx, (_what))
+#define SYM_LOCK_DESTROY() mtx_destroy(&np->mtx)
+#define SYM_LOCK_INIT() mtx_init(&np->mtx, "sym_lock", NULL, MTX_DEF)
+#define SYM_LOCK_INITIALIZED() mtx_initialized(&np->mtx)
+#define SYM_UNLOCK() mtx_unlock(&np->mtx)
+
#define SYM_SNOOP_TIMEOUT (10000000)
#define SYM_PCI_IO PCIR_BAR(0)
#define SYM_PCI_MMIO PCIR_BAR(1)
@@ -1396,6 +1403,7 @@ struct sym_ccb {
/*
* Pointer to CAM ccb and related stuff.
*/
+ struct callout ch; /* callout handle */
union ccb *cam_ccb; /* CAM scsiio ccb */
u8 cdb_buf[16]; /* Copy of CDB */
u8 *sns_bbuf; /* Bounce buffer for sense data */
@@ -1462,6 +1470,8 @@ struct sym_ccb {
* Host Control Block
*/
struct sym_hcb {
+ struct mtx mtx;
+
/*
* Global headers.
* Due to poorness of addressing capabilities, earlier
@@ -1566,12 +1576,6 @@ struct sym_hcb {
* deals with part of the BUS stuff complexity only to fit O/S
* requirements.
*/
- bus_space_handle_t io_bsh;
- bus_space_tag_t io_tag;
- bus_space_handle_t mmio_bsh;
- bus_space_tag_t mmio_tag;
- bus_space_handle_t ram_bsh;
- bus_space_tag_t ram_tag;
/*
* DMA stuff.
@@ -1579,18 +1583,13 @@ struct sym_hcb {
bus_dma_tag_t bus_dmat; /* DMA tag from parent BUS */
bus_dma_tag_t data_dmat; /* DMA tag for user data */
/*
- * Virtual and physical bus addresses of the chip.
+ * BUS addresses of the chip
*/
- vm_offset_t mmio_va; /* MMIO kernel virtual address */
- vm_offset_t mmio_pa; /* MMIO CPU physical address */
vm_offset_t mmio_ba; /* MMIO BUS address */
int mmio_ws; /* MMIO Window size */
- vm_offset_t ram_va; /* RAM kernel virtual address */
- vm_offset_t ram_pa; /* RAM CPU physical address */
vm_offset_t ram_ba; /* RAM BUS address */
int ram_ws; /* RAM window size */
- u32 io_port; /* IO port address */
/*
* SCRIPTS virtual and physical bus addresses.
@@ -2265,11 +2264,10 @@ static void sym_getclock (hcb_p np, int mult);
static int sym_getpciclock (hcb_p np);
static void sym_complete_ok (hcb_p np, ccb_p cp);
static void sym_complete_error (hcb_p np, ccb_p cp);
-static void sym_timeout (void *arg);
+static void sym_callout (void *arg);
static int sym_abort_scsiio (hcb_p np, union ccb *ccb, int timed_out);
static void sym_reset_dev (hcb_p np, union ccb *ccb);
static void sym_action (struct cam_sim *sim, union ccb *ccb);
-static void sym_action1 (struct cam_sim *sim, union ccb *ccb);
static int sym_setup_cdb (hcb_p np, struct ccb_scsiio *csio, ccb_p cp);
static void sym_setup_data_and_start (hcb_p np, struct ccb_scsiio *csio,
ccb_p cp);
@@ -2348,13 +2346,19 @@ static __inline int sym_get_cam_status(union ccb *ccb)
/*
* Enqueue a CAM CCB.
*/
-static void sym_enqueue_cam_ccb(hcb_p np, union ccb *ccb)
+static void sym_enqueue_cam_ccb(ccb_p cp)
{
+ hcb_p np;
+ union ccb *ccb;
+
+ ccb = cp->cam_ccb;
+ np = (hcb_p) cp->arg;
+
assert(!(ccb->ccb_h.status & CAM_SIM_QUEUED));
ccb->ccb_h.status = CAM_REQ_INPROG;
- ccb->ccb_h.timeout_ch = timeout(sym_timeout, (caddr_t) ccb,
- ccb->ccb_h.timeout*hz/1000);
+ callout_reset(&cp->ch, ccb->ccb_h.timeout * hz / 1000, sym_callout,
+ (caddr_t) ccb);
ccb->ccb_h.status |= CAM_SIM_QUEUED;
ccb->ccb_h.sym_hcb_ptr = np;
@@ -2364,23 +2368,37 @@ static void sym_enqueue_cam_ccb(hcb_p np, union ccb *ccb)
/*
* Complete a pending CAM CCB.
*/
-static void sym_xpt_done(hcb_p np, union ccb *ccb)
+static void _sym_xpt_done(hcb_p np, union ccb *ccb)
{
+ SYM_LOCK_ASSERT(MA_OWNED);
+
+ KASSERT((ccb->ccb_h.status & CAM_SIM_QUEUED) == 0,
+ ("%s: status=CAM_SIM_QUEUED", __func__));
+
+ if (ccb->ccb_h.flags & CAM_DEV_QFREEZE)
+ sym_freeze_cam_ccb(ccb);
+ xpt_done(ccb);
+}
+
+static void sym_xpt_done(hcb_p np, union ccb *ccb, ccb_p cp)
+{
+ SYM_LOCK_ASSERT(MA_OWNED);
+
if (ccb->ccb_h.status & CAM_SIM_QUEUED) {
- untimeout(sym_timeout, (caddr_t) ccb, ccb->ccb_h.timeout_ch);
+ callout_stop(&cp->ch);
sym_remque(sym_qptr(&ccb->ccb_h.sim_links));
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
ccb->ccb_h.sym_hcb_ptr = NULL;
}
- if (ccb->ccb_h.flags & CAM_DEV_QFREEZE)
- sym_freeze_cam_ccb(ccb);
- xpt_done(ccb);
+ _sym_xpt_done(np, ccb);
}
static void sym_xpt_done2(hcb_p np, union ccb *ccb, int cam_status)
{
+ SYM_LOCK_ASSERT(MA_OWNED);
+
sym_set_cam_status(ccb, cam_status);
- sym_xpt_done(np, ccb);
+ _sym_xpt_done(np, ccb);
}
/*
@@ -3070,6 +3088,8 @@ static int sym_wakeup_done (hcb_p np)
int i, n;
u32 dsa;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
n = 0;
i = np->dqueueget;
while (1) {
@@ -3123,6 +3143,8 @@ static void sym_init (hcb_p np, int reason)
int i;
u32 phys;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Reset chip if asked, otherwise just clear fifos.
*/
@@ -3824,6 +3846,8 @@ static void sym_intr1 (hcb_p np)
u_char dstat;
u_short sist;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* interrupt on the fly ?
*
@@ -3961,16 +3985,18 @@ unknown_int:
static void sym_intr(void *arg)
{
+ hcb_p np = arg;
+
+ SYM_LOCK();
if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
sym_intr1((hcb_p) arg);
if (DEBUG_FLAGS & DEBUG_TINY) printf ("]");
+ SYM_UNLOCK();
}
static void sym_poll(struct cam_sim *sim)
{
- int s = splcam();
- sym_intr(cam_sim_softc(sim));
- splx(s);
+ sym_intr1(cam_sim_softc(sim));
}
@@ -4634,9 +4660,9 @@ sym_flush_comp_queue(hcb_p np, int cam_status)
ccb = cp->cam_ccb;
if (cam_status)
sym_set_cam_status(ccb, cam_status);
- sym_free_ccb(np, cp);
sym_freeze_cam_ccb(ccb);
- sym_xpt_done(np, ccb);
+ sym_xpt_done(np, ccb, cp);
+ sym_free_ccb(np, cp);
}
}
@@ -4668,6 +4694,8 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp)
int nego;
int i;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Compute the index of the next job to start from SCRIPTS.
*/
@@ -6010,6 +6038,8 @@ static void sym_int_sir (hcb_p np)
tcb_p tp = &np->target[target];
int tmp;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num);
switch (num) {
@@ -6275,7 +6305,7 @@ static ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order)
* Look for a free CCB
*/
if (sym_que_empty(&np->free_ccbq))
- (void) sym_alloc_ccb(np);
+ goto out;
qp = sym_remque_head(&np->free_ccbq);
if (!qp)
goto out;
@@ -6483,6 +6513,8 @@ static ccb_p sym_alloc_ccb(hcb_p np)
ccb_p cp = NULL;
int hcode;
+ SYM_LOCK_ASSERT(MA_NOTOWNED);
+
/*
* Prevent from allocating more CCBs than we can
* queue to the controller.
@@ -6495,7 +6527,7 @@ static ccb_p sym_alloc_ccb(hcb_p np)
*/
cp = sym_calloc_dma(sizeof(struct sym_ccb), "CCB");
if (!cp)
- goto out_free;
+ return NULL;
/*
* Allocate a bounce buffer for sense data.
@@ -6515,6 +6547,11 @@ static ccb_p sym_alloc_ccb(hcb_p np)
np->actccbs++;
/*
+ * Initialize the callout.
+ */
+ callout_init(&cp->ch, 1);
+
+ /*
* Compute the bus address of this ccb.
*/
cp->ccb_ba = vtobus(cp);
@@ -6544,11 +6581,9 @@ static ccb_p sym_alloc_ccb(hcb_p np)
return cp;
out_free:
- if (cp) {
- if (cp->sns_bbuf)
- sym_mfree_dma(cp->sns_bbuf,SYM_SNS_BBUF_LEN,"SNS_BBUF");
- sym_mfree_dma(cp, sizeof(*cp), "CCB");
- }
+ if (cp->sns_bbuf)
+ sym_mfree_dma(cp->sns_bbuf, SYM_SNS_BBUF_LEN, "SNS_BBUF");
+ sym_mfree_dma(cp, sizeof(*cp), "CCB");
return NULL;
}
@@ -7117,6 +7152,8 @@ static void sym_complete_error (hcb_p np, ccb_p cp)
u_int cam_status;
int i;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Paranoid check. :)
*/
@@ -7265,6 +7302,8 @@ static void sym_complete_ok (hcb_p np, ccb_p cp)
tcb_p tp;
lcb_p lp;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Paranoid check. :)
*/
@@ -7314,14 +7353,14 @@ static void sym_complete_ok (hcb_p np, ccb_p cp)
*/
csio->scsi_status = cp->ssss_status;
sym_set_cam_status((union ccb *) csio, CAM_REQ_CMP);
- sym_free_ccb (np, cp);
- sym_xpt_done(np, (union ccb *) csio);
+ sym_xpt_done(np, (union ccb *) csio, cp);
+ sym_free_ccb(np, cp);
}
/*
- * Our timeout handler.
+ * Our callout handler
*/
-static void sym_timeout1(void *arg)
+static void sym_callout(void *arg)
{
union ccb *ccb = (union ccb *) arg;
hcb_p np = ccb->ccb_h.sym_hcb_ptr;
@@ -7332,6 +7371,8 @@ static void sym_timeout1(void *arg)
if (!np)
return;
+ SYM_LOCK();
+
switch(ccb->ccb_h.func_code) {
case XPT_SCSI_IO:
(void) sym_abort_scsiio(np, ccb, 1);
@@ -7339,13 +7380,8 @@ static void sym_timeout1(void *arg)
default:
break;
}
-}
-static void sym_timeout(void *arg)
-{
- int s = splcam();
- sym_timeout1(arg);
- splx(s);
+ SYM_UNLOCK();
}
/*
@@ -7356,6 +7392,8 @@ static int sym_abort_scsiio(hcb_p np, union ccb *ccb, int timed_out)
ccb_p cp;
SYM_QUEHEAD *qp;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Look up our CCB control block.
*/
@@ -7383,7 +7421,7 @@ static int sym_abort_scsiio(hcb_p np, union ccb *ccb, int timed_out)
* Mark the CCB for abort and allow time for.
*/
cp->to_abort = timed_out ? 2 : 1;
- ccb->ccb_h.timeout_ch = timeout(sym_timeout, (caddr_t) ccb, 10*hz);
+ callout_reset(&cp->ch, 10 * hz, sym_callout, (caddr_t) ccb);
/*
* Tell the SCRIPTS processor to stop and synchronize with us.
@@ -7401,6 +7439,8 @@ static void sym_reset_dev(hcb_p np, union ccb *ccb)
tcb_p tp;
struct ccb_hdr *ccb_h = &ccb->ccb_h;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
if (ccb_h->target_id == np->myaddr ||
ccb_h->target_id >= SYM_CONF_MAX_TARGET ||
ccb_h->target_lun >= SYM_CONF_MAX_LUN) {
@@ -7422,13 +7462,6 @@ static void sym_reset_dev(hcb_p np, union ccb *ccb)
*/
static void sym_action(struct cam_sim *sim, union ccb *ccb)
{
- int s = splcam();
- sym_action1(sim, ccb);
- splx(s);
-}
-
-static void sym_action1(struct cam_sim *sim, union ccb *ccb)
-{
hcb_p np;
tcb_p tp;
lcb_p lp;
@@ -7446,6 +7479,8 @@ static void sym_action1(struct cam_sim *sim, union ccb *ccb)
*/
np = (hcb_p) cam_sim_softc(sim);
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* The common case is SCSI IO.
* We deal with other ones elsewhere.
@@ -7603,8 +7638,8 @@ static void sym_action1(struct cam_sim *sim, union ccb *ccb)
* command
*/
if (sym_setup_cdb(np, csio, cp) < 0) {
+ sym_xpt_done(np, ccb, cp);
sym_free_ccb(np, cp);
- sym_xpt_done(np, ccb);
return;
}
@@ -7646,6 +7681,8 @@ static int sym_setup_cdb(hcb_p np, struct ccb_scsiio *csio, ccb_p cp)
u32 cmd_ba;
int cmd_len;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
ccb_h = &csio->ccb_h;
/*
@@ -7692,6 +7729,8 @@ sym_setup_data_pointers(hcb_p np, ccb_p cp, int dir)
{
u32 lastp, goalp;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* No segments means no data.
*/
@@ -7735,14 +7774,13 @@ sym_execute_ccb(void *arg, bus_dma_segment_t *psegs, int nsegs, int error)
ccb_p cp;
hcb_p np;
union ccb *ccb;
- int s;
-
- s = splcam();
cp = (ccb_p) arg;
ccb = cp->cam_ccb;
np = (hcb_p) cp->arg;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Deal with weird races.
*/
@@ -7798,7 +7836,7 @@ sym_execute_ccb(void *arg, bus_dma_segment_t *psegs, int nsegs, int error)
/*
* Enqueue this IO in our pending queue.
*/
- sym_enqueue_cam_ccb(np, ccb);
+ sym_enqueue_cam_ccb(cp);
/*
* When `#ifed 1', the code below makes the driver
@@ -7820,13 +7858,10 @@ sym_execute_ccb(void *arg, bus_dma_segment_t *psegs, int nsegs, int error)
* Activate this job.
*/
sym_put_start_queue(np, cp);
-out:
- splx(s);
return;
out_abort:
+ sym_xpt_done(np, ccb, cp);
sym_free_ccb(np, cp);
- sym_xpt_done(np, ccb);
- goto out;
}
/*
@@ -7839,6 +7874,8 @@ sym_setup_data_and_start(hcb_p np, struct ccb_scsiio *csio, ccb_p cp)
struct ccb_hdr *ccb_h;
int dir, retv;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
ccb_h = &csio->ccb_h;
/*
@@ -7860,11 +7897,8 @@ sym_setup_data_and_start(hcb_p np, struct ccb_scsiio *csio, ccb_p cp)
/* Single buffer */
if (!(ccb_h->flags & CAM_DATA_PHYS)) {
/* Buffer is virtual */
- int s;
-
cp->dmamapped = (dir == CAM_DIR_IN) ?
SYM_DMA_READ : SYM_DMA_WRITE;
- s = splsoftvm();
retv = bus_dmamap_load(np->data_dmat, cp->dmamap,
csio->data_ptr, csio->dxfer_len,
sym_execute_ccb, cp, 0);
@@ -7873,7 +7907,6 @@ sym_setup_data_and_start(hcb_p np, struct ccb_scsiio *csio, ccb_p cp)
xpt_freeze_simq(np->sim, 1);
csio->ccb_h.status |= CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
/* Buffer is physical */
struct bus_dma_segment seg;
@@ -7903,8 +7936,8 @@ sym_setup_data_and_start(hcb_p np, struct ccb_scsiio *csio, ccb_p cp)
}
return;
out_abort:
+ sym_xpt_done(np, (union ccb *) csio, cp);
sym_free_ccb(np, cp);
- sym_xpt_done(np, (union ccb *) csio);
}
/*
@@ -7917,6 +7950,8 @@ sym_fast_scatter_sg_physical(hcb_p np, ccb_p cp,
struct sym_tblmove *data;
bus_dma_segment_t *psegs2;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
if (nsegs > SYM_CONF_MAX_SG)
return -1;
@@ -7956,6 +7991,8 @@ sym_scatter_sg_physical(hcb_p np, ccb_p cp, bus_dma_segment_t *psegs, int nsegs)
u_long k;
int s, t;
+ SYM_LOCK_ASSERT(MA_OWNED);
+
s = SYM_CONF_MAX_SG - 1;
t = nsegs - 1;
ps = psegs[t].ds_addr;
@@ -8004,6 +8041,8 @@ static void sym_action2(struct cam_sim *sim, union ccb *ccb)
*/
np = (hcb_p) cam_sim_softc(sim);
+ SYM_LOCK_ASSERT(MA_OWNED);
+
ccb_h = &ccb->ccb_h;
switch (ccb_h->func_code) {
@@ -8182,13 +8221,12 @@ sym_async(void *cb_arg, u32 code, struct cam_path *path, void *arg)
struct cam_sim *sim;
u_int tn;
tcb_p tp;
- int s;
-
- s = splcam();
sim = (struct cam_sim *) cb_arg;
np = (hcb_p) cam_sim_softc(sim);
+ SYM_LOCK_ASSERT(MA_OWNED);
+
switch (code) {
case AC_LOST_DEVICE:
tn = xpt_path_target_id(path);
@@ -8211,8 +8249,6 @@ sym_async(void *cb_arg, u32 code, struct cam_path *path, void *arg)
default:
break;
}
-
- splx(s);
}
/*
@@ -8221,6 +8257,8 @@ sym_async(void *cb_arg, u32 code, struct cam_path *path, void *arg)
static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
struct ccb_trans_settings *cts)
{
+ SYM_LOCK_ASSERT(MA_OWNED);
+
/*
* Update the infos.
*/
@@ -8288,6 +8326,8 @@ static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
static void
sym_update_dflags(hcb_p np, u_char *flags, struct ccb_trans_settings *cts)
{
+ SYM_LOCK_ASSERT(MA_OWNED);
+
#define cts__scsi (&cts->proto_specific.scsi)
#define cts__spi (&cts->xport_specific.spi)
if ((cts__spi->valid & CTS_SPI_VALID_DISC) != 0) {
@@ -8320,7 +8360,7 @@ static device_method_t sym_pci_methods[] = {
static driver_t sym_pci_driver = {
"sym",
sym_pci_methods,
- sizeof(struct sym_hcb)
+ 1 /* no softc */
};
static devclass_t sym_devclass;
@@ -8497,7 +8537,9 @@ sym_pci_attach(device_t dev)
if (np)
np->bus_dmat = bus_dmat;
else
- goto attach_failed;
+ return (ENXIO);
+
+ SYM_LOCK_INIT();
/*
* Copy some useful infos to the HCB.
@@ -8544,7 +8586,7 @@ sym_pci_attach(device_t dev)
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
NULL, NULL,
BUS_SPACE_MAXSIZE, SYM_CONF_MAX_SG,
- (1<<24), 0, busdma_lock_mutex, &Giant,
+ (1<<24), 0, busdma_lock_mutex, &np->mtx,
&np->data_dmat)) {
device_printf(dev, "failed to create DMA tag.\n");
goto attach_failed;
@@ -8584,11 +8626,7 @@ sym_pci_attach(device_t dev)
device_printf(dev, "failed to allocate MMIO resources\n");
goto attach_failed;
}
- np->mmio_bsh = rman_get_bushandle(np->mmio_res);
- np->mmio_tag = rman_get_bustag(np->mmio_res);
- np->mmio_pa = rman_get_start(np->mmio_res);
- np->mmio_va = (vm_offset_t) rman_get_virtual(np->mmio_res);
- np->mmio_ba = np->mmio_pa;
+ np->mmio_ba = rman_get_start(np->mmio_res);
/*
* Allocate the IRQ.
@@ -8615,9 +8653,6 @@ sym_pci_attach(device_t dev)
device_printf(dev, "failed to allocate IO resources\n");
goto attach_failed;
}
- np->io_bsh = rman_get_bushandle(np->io_res);
- np->io_tag = rman_get_bustag(np->io_res);
- np->io_port = rman_get_start(np->io_res);
#endif /* SYM_CONF_IOMAPPED */
@@ -8637,11 +8672,7 @@ sym_pci_attach(device_t dev)
goto attach_failed;
}
np->ram_id = regs_id;
- np->ram_bsh = rman_get_bushandle(np->ram_res);
- np->ram_tag = rman_get_bustag(np->ram_res);
- np->ram_pa = rman_get_start(np->ram_res);
- np->ram_va = (vm_offset_t) rman_get_virtual(np->ram_res);
- np->ram_ba = np->ram_pa;
+ np->ram_ba = rman_get_start(np->ram_res);
}
/*
@@ -8710,9 +8741,11 @@ sym_pci_attach(device_t dev)
goto attach_failed;
/*
- * Allocate some CCB. We need at least ONE.
+ * Allocate the CCBs. We need at least ONE.
*/
- if (!sym_alloc_ccb(np))
+ for (i = 0; sym_alloc_ccb(np) != NULL; i++)
+ ;
+ if (i < 1)
goto attach_failed;
/*
@@ -8857,14 +8890,11 @@ static void sym_pci_free(hcb_p np)
tcb_p tp;
lcb_p lp;
int target, lun;
- int s;
/*
* First free CAM resources.
*/
- s = splcam();
sym_cam_free(np);
- splx(s);
/*
* Now every should be quiet for us to
@@ -8931,6 +8961,8 @@ static void sym_pci_free(hcb_p np)
sym_mfree_dma(np->targtbl, 256, "TARGTBL");
if (np->data_dmat)
bus_dma_tag_destroy(np->data_dmat);
+ if (SYM_LOCK_INITIALIZED() != 0)
+ SYM_LOCK_DESTROY();
sym_mfree_dma(np, sizeof(*np), "HCB");
}
@@ -8943,16 +8975,14 @@ static int sym_cam_attach(hcb_p np)
struct cam_sim *sim = NULL;
struct cam_path *path = NULL;
struct ccb_setasync csa;
- int err, s;
-
- s = splcam();
+ int err;
/*
* Establish our interrupt handler.
*/
err = bus_setup_intr(np->device, np->irq_res,
- INTR_TYPE_CAM | INTR_ENTROPY, NULL, sym_intr, np,
- &np->intr);
+ INTR_ENTROPY | INTR_MPSAFE | INTR_TYPE_CAM,
+ NULL, sym_intr, np, &np->intr);
if (err) {
device_printf(np->device, "bus_setup_intr() failed: %d\n",
err);
@@ -8970,15 +9000,15 @@ static int sym_cam_attach(hcb_p np)
* Construct our SIM entry.
*/
sim = cam_sim_alloc(sym_action, sym_poll, "sym", np, np->unit,
- &Giant, 1, SYM_SETUP_MAX_TAG, devq);
+ &np->mtx, 1, SYM_SETUP_MAX_TAG, devq);
if (!sim)
goto fail;
- devq = 0;
+
+ SYM_LOCK();
if (xpt_bus_register(sim, np->device, 0) != CAM_SUCCESS)
goto fail;
np->sim = sim;
- sim = 0;
if (xpt_create_path(&path, 0,
cam_sim_path(np->sim), CAM_TARGET_WILDCARD,
@@ -9005,7 +9035,7 @@ static int sym_cam_attach(hcb_p np)
*/
sym_init (np, 0);
- splx(s);
+ SYM_UNLOCK();
return 1;
fail:
if (sim)
@@ -9013,9 +9043,10 @@ fail:
if (devq)
cam_simq_free(devq);
+ SYM_UNLOCK();
+
sym_cam_free(np);
- splx(s);
return 0;
}
@@ -9024,11 +9055,15 @@ fail:
*/
static void sym_cam_free(hcb_p np)
{
+ SYM_LOCK_ASSERT(MA_NOTOWNED);
+
if (np->intr) {
bus_teardown_intr(np->device, np->irq_res, np->intr);
np->intr = NULL;
}
+ SYM_LOCK();
+
if (np->sim) {
xpt_bus_deregister(cam_sim_path(np->sim));
cam_sim_free(np->sim, /*free_devq*/ TRUE);
@@ -9038,6 +9073,8 @@ static void sym_cam_free(hcb_p np)
xpt_free_path(np->path);
np->path = NULL;
}
+
+ SYM_UNLOCK();
}
/*============ OPTIONNAL NVRAM SUPPORT =================*/