mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-24 11:29:10 +00:00
- 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
This commit is contained in:
parent
6b0c4e979e
commit
82897554f5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178468
@ -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)
|
||||
{
|
||||
if (ccb->ccb_h.status & CAM_SIM_QUEUED) {
|
||||
untimeout(sym_timeout, (caddr_t) ccb, ccb->ccb_h.timeout_ch);
|
||||
sym_remque(sym_qptr(&ccb->ccb_h.sim_links));
|
||||
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
|
||||
ccb->ccb_h.sym_hcb_ptr = NULL;
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
_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 @@ static void sym_intr1 (hcb_p np)
|
||||
|
||||
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.
|
||||
@ -6514,6 +6546,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.
|
||||
*/
|
||||
@ -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) {
|
||||
@ -7421,13 +7461,6 @@ static void sym_reset_dev(hcb_p np, union ccb *ccb)
|
||||
* SIM action entry point.
|
||||
*/
|
||||
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;
|
||||
@ -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 @@ static int sym_cam_attach(hcb_p np)
|
||||
if (devq)
|
||||
cam_simq_free(devq);
|
||||
|
||||
SYM_UNLOCK();
|
||||
|
||||
sym_cam_free(np);
|
||||
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -9024,11 +9055,15 @@ static int sym_cam_attach(hcb_p np)
|
||||
*/
|
||||
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 =================*/
|
||||
|
Loading…
Reference in New Issue
Block a user