Skip to content

Commit

Permalink
MFC: r182876
Browse files Browse the repository at this point in the history
Adapt the locking of esp(4) to MPSAFE cam(4) (so that ncr53c9x_intr()
actually is INTR_MPSAFE now) and fix a couple of bugs which lead to
panics, amongst other improvements.

Approved by:	re (kib)
  • Loading branch information
sparcplug committed Nov 16, 2008
1 parent fd3615f commit f0aa666
Show file tree
Hide file tree
Showing 8 changed files with 765 additions and 613 deletions.
233 changes: 114 additions & 119 deletions sys/dev/esp/esp_sbus.c

Large diffs are not rendered by default.

833 changes: 492 additions & 341 deletions sys/dev/esp/ncr53c9x.c

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions sys/dev/esp/ncr53c9xreg.h
Expand Up @@ -84,8 +84,8 @@
#define NCRSTAT_PHASE 0x07 /* Phase bits */

#define NCR_SELID 0x04 /* WO - Select/Reselect Bus ID */
#define NCR_BUSID_HME 0x10 /* XXX HME reselect ID */
#define NCR_BUSID_HME32 0x40 /* XXX HME to select more than 16 */
#define NCR_BUSID_HMEXC32 0x40 /* HME xfer counter is 32bit */
#define NCR_BUSID_HMEENCID 0x10 /* HME encode reselection ID */

#define NCR_INTR 0x05 /* RO - Interrupt */
#define NCRINTR_SBR 0x80 /* SCSI Bus Reset */
Expand Down
64 changes: 36 additions & 28 deletions sys/dev/esp/ncr53c9xvar.h
Expand Up @@ -110,9 +110,9 @@
* ECB. Holds additional information for each SCSI command Comments: We
* need a separate scsi command block because we may need to overwrite it
* with a request sense command. Basicly, we refrain from fiddling with
* the scsipi_xfer struct (except do the expected updating of return values).
* We'll generally update: xs->{flags,resid,error,sense,status} and
* occasionally xs->retries.
* the ccb union (except do the expected updating of return values).
* We'll generally update: ccb->ccb_h.status and ccb->csio.{resid,
* scsi_status,sense_data}.
*/
struct ncr53c9x_ecb {
/* These fields are preserved between alloc and free */
Expand All @@ -130,6 +130,7 @@ struct ncr53c9x_ecb {
#define ECB_RESET 0x80
#define ECB_TENTATIVE_DONE 0x100
int timeout;
struct callout ch;

struct {
u_char msg[3]; /* Selection Id msg and tags */
Expand Down Expand Up @@ -180,25 +181,26 @@ struct ncr53c9x_linfo {
struct ncr53c9x_ecb *queued[NCR_TAG_DEPTH];
};

struct ncr53c9x_xinfo {
u_char period;
u_char offset;
u_char width;
};

struct ncr53c9x_tinfo {
int cmds; /* # of commands processed */
int dconns; /* # of disconnects */
int touts; /* # of timeouts */
int perrs; /* # of parity errors */
int senses; /* # of request sense commands sent */
u_char flags;
#define T_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */
#define T_SYNCMODE 0x08 /* SYNC mode has been negotiated */
#define T_SYNCHOFF 0x10 /* SYNC mode for is permanently off */
#define T_RSELECTOFF 0x20 /* RE-SELECT mode is off */
#define T_TAG 0x40 /* Turn on TAG QUEUEs */
#define T_WIDE 0x80 /* Negotiate wide options */
#define T_WDTRSENT 0x04 /* WDTR message has been sent to */
u_char period; /* Period suggestion */
u_char offset; /* Offset suggestion */
u_char cfg3; /* per target config 3 */
u_char nextag; /* Next available tag */
u_char width; /* width suggesion */
#define T_SYNCHOFF 0x01 /* SYNC mode is permanently off */
#define T_RSELECTOFF 0x02 /* RE-SELECT mode is off */
#define T_TAG 0x04 /* Turn on TAG QUEUEs */
#define T_SDTRSENT 0x08 /* SDTR message has been sent to */
#define T_WDTRSENT 0x10 /* WDTR message has been sent to */
struct ncr53c9x_xinfo curr;
struct ncr53c9x_xinfo goal;
LIST_HEAD(lun_list, ncr53c9x_linfo) luns;
struct ncr53c9x_linfo *lun[NCR_NLUN]; /* For speedy lookups */
};
Expand Down Expand Up @@ -352,7 +354,6 @@ struct ncr53c9x_softc {
int sc_features; /* Chip features */
int sc_minsync; /* Minimum sync period / 4 */
int sc_maxxfer; /* Maximum transfer size */
int sc_maxsync; /* Maximum sync period */
int sc_maxoffset; /* Maximum offset */
int sc_maxwidth; /* Maximum width */
int sc_extended_geom; /* Should we return extended geometry */
Expand All @@ -377,12 +378,10 @@ struct ncr53c9x_softc {
/* values for sc_flags */
#define NCR_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
#define NCR_ABORTING 0x02 /* Bailing out */
#define NCR_DOINGDMA 0x04 /* The FIFO data path is active! */
#define NCR_SYNCHNEGO 0x08 /* Synch negotiation in progress. */
#define NCR_ICCS 0x10 /* Expect status phase results */
#define NCR_WAITI 0x20 /* Waiting for non-DMA data to arrive */
#define NCR_ATN 0x40 /* ATN asserted */
#define NCR_EXPECT_ILLCMD 0x80 /* Expect Illegal Command Interrupt */
#define NCR_ICCS 0x04 /* Expect status phase results */
#define NCR_WAITI 0x08 /* Waiting for non-DMA data to arrive */
#define NCR_ATN 0x10 /* ATN asserted */
#define NCR_EXPECT_ILLCMD 0x20 /* Expect Illegal Command Interrupt */

/* values for sc_features */
#define NCR_F_HASCFG3 0x01 /* chip has CFG3 register */
Expand All @@ -397,9 +396,9 @@ struct ncr53c9x_softc {
#define SEND_REJECT 0x0008
#define SEND_IDENTIFY 0x0010
#define SEND_ABORT 0x0020
#define SEND_WDTR 0x0040
#define SEND_SDTR 0x0080
#define SEND_TAG 0x0100
#define SEND_TAG 0x0040
#define SEND_WDTR 0x0080
#define SEND_SDTR 0x0100

/* SCSI Status codes */
#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
Expand Down Expand Up @@ -443,6 +442,17 @@ struct ncr53c9x_softc {
#define NCRCMD(sc, cmd) NCR_WRITE_REG(sc, NCR_CMD, cmd)
#endif

/*
* Macros for locking
*/
#define NCR_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_lock, "ncr", "ncr53c9x lock", MTX_DEF);
#define NCR_LOCK_INITIALIZED(_sc) mtx_initialized(&(_sc)->sc_lock)
#define NCR_LOCK(_sc) mtx_lock(&(_sc)->sc_lock)
#define NCR_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock)
#define NCR_LOCK_ASSERT(_sc, _what) mtx_assert(&(_sc)->sc_lock, (_what))
#define NCR_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_lock)

/*
* DMA macros for NCR53c9x
*/
Expand All @@ -452,6 +462,7 @@ struct ncr53c9x_softc {
#define NCRDMA_SETUP(sc, addr, len, datain, dmasize) \
(*(sc)->sc_glue->gl_dma_setup)((sc), (addr), (len), (datain), (dmasize))
#define NCRDMA_GO(sc) (*(sc)->sc_glue->gl_dma_go)((sc))
#define NCRDMA_STOP(sc) (*(sc)->sc_glue->gl_dma_stop)((sc))
#define NCRDMA_ISACTIVE(sc) (*(sc)->sc_glue->gl_dma_isactive)((sc))

/*
Expand All @@ -463,9 +474,6 @@ struct ncr53c9x_softc {

int ncr53c9x_attach(struct ncr53c9x_softc *sc);
int ncr53c9x_detach(struct ncr53c9x_softc *sc);
void ncr53c9x_action(struct cam_sim *sim, union ccb *ccb);
void ncr53c9x_reset(struct ncr53c9x_softc *sc);
void ncr53c9x_intr(void *arg);
void ncr53c9x_init(struct ncr53c9x_softc *sc, int doreset);

#endif /* _DEV_IC_NCR53C9XVAR_H_ */
62 changes: 36 additions & 26 deletions sys/dev/le/if_le_ledma.c
Expand Up @@ -78,12 +78,8 @@ __FBSDID("$FreeBSD$");
struct le_dma_softc {
struct am7990_softc sc_am7990; /* glue to MI code */

int sc_rrid;
struct resource *sc_rres;
bus_space_tag_t sc_regt;
bus_space_handle_t sc_regh;

int sc_irid;
struct resource *sc_ires;
void *sc_ih;

Expand Down Expand Up @@ -115,6 +111,7 @@ static device_method_t le_dma_methods[] = {

DEFINE_CLASS_0(le, le_dma_driver, le_dma_methods, sizeof(struct le_dma_softc));
DRIVER_MODULE(le, dma, le_dma_driver, le_devclass, 0, 0);
MODULE_DEPEND(le, dma, 1, 1, 1);
MODULE_DEPEND(le, ether, 1, 1, 1);

/*
Expand Down Expand Up @@ -142,21 +139,19 @@ le_dma_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
{
struct le_dma_softc *lesc = (struct le_dma_softc *)sc;

bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port);
bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2,
BUS_SPACE_BARRIER_WRITE);
bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP, val);
bus_write_2(lesc->sc_rres, LEREG1_RAP, port);
bus_barrier(lesc->sc_rres, LEREG1_RAP, 2, BUS_SPACE_BARRIER_WRITE);
bus_write_2(lesc->sc_rres, LEREG1_RDP, val);
}

static uint16_t
le_dma_rdcsr(struct lance_softc *sc, uint16_t port)
{
struct le_dma_softc *lesc = (struct le_dma_softc *)sc;

bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port);
bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2,
BUS_SPACE_BARRIER_WRITE);
return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP));
bus_write_2(lesc->sc_rres, LEREG1_RAP, port);
bus_barrier(lesc->sc_rres, LEREG1_RAP, 2, BUS_SPACE_BARRIER_WRITE);
return (bus_read_2(lesc->sc_rres, LEREG1_RDP));
}

static void
Expand Down Expand Up @@ -238,7 +233,7 @@ le_dma_hwreset(struct lance_softc *sc)
DMA_RESET(dma);

/* Write bits 24-31 of Lance address. */
bus_space_write_4(dma->sc_regt, dma->sc_regh, L64854_REG_ENBAR,
bus_write_4(dma->sc_res, L64854_REG_ENBAR,
lesc->sc_laddr & 0xff000000);

DMA_ENINTR(dma);
Expand Down Expand Up @@ -319,7 +314,7 @@ le_dma_attach(device_t dev)
struct le_dma_softc *lesc;
struct lsi64854_softc *dma;
struct lance_softc *sc;
int error;
int error, i;

lesc = device_get_softc(dev);
sc = &lesc->sc_am7990.lsc;
Expand All @@ -334,25 +329,30 @@ le_dma_attach(device_t dev)
lesc->sc_dma = dma;
lesc->sc_dma->sc_client = lesc;

lesc->sc_rrid = 0;
i = 0;
lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&lesc->sc_rrid, RF_ACTIVE);
&i, RF_ACTIVE);
if (lesc->sc_rres == NULL) {
device_printf(dev, "cannot allocate registers\n");
error = ENXIO;
goto fail_mtx;
}
lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);

lesc->sc_irid = 0;
i = 0;
if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
&i, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "cannot allocate interrupt\n");
error = ENXIO;
goto fail_rres;
}

/* Attach the DMA engine. */
error = lsi64854_attach(dma);
if (error != 0) {
device_printf(dev, "lsi64854_attach failed\n");
goto fail_ires;
}

sc->sc_memsize = LEDMA_MEMSIZE;
error = bus_dma_tag_create(
dma->sc_parent_dmat, /* parent */
Expand All @@ -369,7 +369,7 @@ le_dma_attach(device_t dev)
&lesc->sc_dmat);
if (error != 0) {
device_printf(dev, "cannot allocate buffer DMA tag\n");
goto fail_ires;
goto fail_lsi;
}

error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
Expand All @@ -383,7 +383,7 @@ le_dma_attach(device_t dev)
error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
sc->sc_memsize, le_dma_dma_callback, lesc, 0);
if (error != 0 || lesc->sc_laddr == 0) {
device_printf(dev, "cannot load DMA buffer map\n");
device_printf(dev, "cannot load DMA buffer map\n");
goto fail_dmem;
}

Expand Down Expand Up @@ -435,10 +435,14 @@ le_dma_attach(device_t dev)
bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
fail_dtag:
bus_dma_tag_destroy(lesc->sc_dmat);
fail_lsi:
lsi64854_detach(dma);
fail_ires:
bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires),
lesc->sc_ires);
fail_rres:
bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres),
lesc->sc_rres);
fail_mtx:
LE_LOCK_DESTROY(sc);
return (error);
Expand All @@ -449,6 +453,7 @@ le_dma_detach(device_t dev)
{
struct le_dma_softc *lesc;
struct lance_softc *sc;
int error;

lesc = device_get_softc(dev);
sc = &lesc->sc_am7990.lsc;
Expand All @@ -458,8 +463,13 @@ le_dma_detach(device_t dev)
bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
bus_dma_tag_destroy(lesc->sc_dmat);
bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres);
error = lsi64854_detach(lesc->sc_dma);
if (error != 0)
return (error);
bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires),
lesc->sc_ires);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres),
lesc->sc_rres);
LE_LOCK_DESTROY(sc);

return (0);
Expand Down
32 changes: 11 additions & 21 deletions sys/sparc64/sbus/dma_sbus.c
Expand Up @@ -70,7 +70,6 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/rman.h>

#include <dev/ofw/ofw_bus.h>
Expand Down Expand Up @@ -178,7 +177,7 @@ dma_attach(device_t dev)
char *cabletype;
uint32_t csr;
phandle_t child, node;
int error, burst, children;
int error, i;

dsc = device_get_softc(dev);
lsc = &dsc->sc_lsi64854;
Expand All @@ -188,15 +187,13 @@ dma_attach(device_t dev)
dsc->sc_ign = sbus_get_ign(dev);
dsc->sc_slot = sbus_get_slot(dev);

lsc->sc_rid = 0;
lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &lsc->sc_rid,
i = 0;
lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
RF_ACTIVE);
if (lsc->sc_res == NULL) {
device_printf(dev, "cannot allocate resources\n");
return (ENXIO);
}
lsc->sc_regt = rman_get_bustag(lsc->sc_res);
lsc->sc_regh = rman_get_bushandle(lsc->sc_res);

if (strcmp(name, "espdma") == 0 || strcmp(name, "dma") == 0)
lsc->sc_channel = L64854_CHANNEL_SCSI;
Expand Down Expand Up @@ -246,23 +243,17 @@ dma_attach(device_t dev)
goto fail_lres;
}

burst = sbus_get_burstsz(dev);
lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
(burst & SBUS_BURST_16) ? 16 : 0;
i = sbus_get_burstsz(dev);
lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
(i & SBUS_BURST_16) ? 16 : 0;
lsc->sc_dev = dev;

error = lsi64854_attach(lsc);
if (error != 0) {
device_printf(dev, "lsi64854_attach failed\n");
goto fail_lpdma;
}

/* Attach children. */
children = 0;
i = 0;
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
if ((ddi = dma_setup_dinfo(dev, dsc, child)) == NULL)
continue;
if (children != 0) {
if (i != 0) {
device_printf(dev,
"<%s>: only one child per DMA channel supported\n",
ddi->ddi_obdinfo.obd_name);
Expand All @@ -276,14 +267,13 @@ dma_attach(device_t dev)
continue;
}
device_set_ivars(cdev, ddi);
children++;
i++;
}
return (bus_generic_attach(dev));

fail_lpdma:
bus_dma_tag_destroy(lsc->sc_parent_dmat);
fail_lres:
bus_release_resource(dev, SYS_RES_MEMORY, lsc->sc_rid, lsc->sc_res);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
lsc->sc_res);
return (error);
}

Expand Down

0 comments on commit f0aa666

Please sign in to comment.