o Move the MODULE_DEPEND() for cam(4) from the esp_sbus.c front-end to

the ncr53c9x.c core where it actually belongs so future front-ends
  don't need to add it.
o Use the correct OFW property when looking for the initiator ID of the
  SBus device.
o Don't specify an alignment when creating the parent DMA tag for
  SUNW,fas; their DMA engine doesn't require an alignment constraint
  and it's no inherited by the child DMA tags anyway (which probably
  is a bug though).
o Drop the superfluous sc_maxsync and use sc_minsync instead. The
  former apparently was added due to a confusion with the maximum
  frequency used in cam(4), which basically corresponds to the
  inverse of minimum sync period.
o Merge ncr53c9x.c from NetBSD:
  1.116: NCRDMA_SETUP() should be called before NCR_SET_COUNT() and
         NCRCMD_DMA command in ncr53c9x_select().
  1.125: free allocated resources on detach.
o Static'ize ncr53c9x_action(), ncr53c9x_init() and ncr53c9x_reset()
  as these are not required outside of ncr53c9x.c.
o In ncr53c9x_attach() don't leak the device mutex in case attaching
  fails.
o Register an asynchronous notification handler so in case cam(4)
  reports a lost device we can cancel outstanding commands and
  restore the default parameters for the target in question.
o For FAS366 correctly support 16-bit target IDs and let it know
  that we use 32-bit transfers.
o Overhaul the negotiation of transfer settings. This includes
  distinguishing between current and goal transfer settings of the
  target so we can renegotiate their goal settings when necessary
  and correcting the order in which tagged, wide and synchronous
  transfers are negotiated.
o If we are requesting sense, force a renegotiation if we are
  currently using anything different from asynchronous at 8 bit
  as the target might have lost our transfer negotiations.
o In case of an XPT_RESET_BUS just directly call ncr53c9x_init()
  instead of issuing a NCRCMD_RSTSCSI, which in turn will issue an
  interrupt that is treated as an unexpected SCSI bus reset by
  ncr53c9x_intr() and thus calls ncr53c9x_init(). Remove the now
  no longer used ncr53c9x_scsi_reset().
o Correct an off-by-one error when setting cpi->max_lun.
o In replace printf(9) with device_printf(9) calls where appropriate
  and in ncr53c9x_action() remove some unnecessarily verbose messages.
o In ncr53c9x_sched() use TAILQ_FOREACH() instead of reimplementing
  it and consolidate two tagging-related target info checks into one.
o In ncr53c9x_done() set the CAM status to CAM_SCSI_STATUS_ERROR when
  appropriate, respect CAM_DIS_AUTOSENSE and teach it to return SCSI
  status information.
o In ncr53c9x_dequeue() ensure the tags are cleared.
o Use ulmin() instead of min() where appropriate.
o In ncr53c9x_msgout() consistently use the reset label.
o When we're interrupted during a data phase and the DMA engine is
  still active, don't panic but reset the core and the DMA engine as
  this should be sufficient. Also, the typical problem for triggering
  this was the lack of renegotiation when requesting sense.
o Correctly handle DEVICE RESETs.
o Adapt the locking of esp(4) to MPSAFE cam(4). This includes moving
  the calls of lsi64854_attach() to the bus front-ends so it can pass
  the esp(4) mutex to bus_dma_tag_create(9).
o Change the LSI64854 driver to not create a DMA tag and map for the
  Ethernet channel as le(4) will handle these on its own as well as
  sync and unload the DMA maps for the SCSI and parallel port channel
  after a DMA transfer.
o Cam(4)'ify some NetBSD-centric comments.
o Use bus_{read,write}_*(9) instead of bus_space_{read,write}_*(9)
  and take advantage of rman_get_rid(9) in order to save some softc
  members.

Reviewed by:	scottl
MFC after:	1 month
This commit is contained in:
Marius Strobl 2008-09-08 20:20:44 +00:00
parent aa4c44b58b
commit 85de9f54f8
8 changed files with 764 additions and 612 deletions

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2004 Scott Long
* Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -71,8 +72,9 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/resource.h>
#include <sys/mutex.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
@ -83,6 +85,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#include <sparc64/sbus/lsi64854reg.h>
#include <sparc64/sbus/lsi64854var.h>
@ -97,12 +100,8 @@ struct esp_softc {
struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
struct device *sc_dev;
int sc_rid;
struct resource *sc_res;
bus_space_handle_t sc_regh;
bus_space_tag_t sc_regt;
int sc_irqrid;
struct resource *sc_irqres;
void *sc_irq;
@ -155,8 +154,6 @@ static driver_t esp_sbus_driver = {
DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0);
MODULE_DEPEND(esp, sbus, 1, 1, 1);
MODULE_DEPEND(esp, cam, 1, 1, 1);
/*
* Functions and the switch for the MI code
*/
@ -170,9 +167,11 @@ static int esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr,
static void esp_dma_go(struct ncr53c9x_softc *sc);
static void esp_dma_stop(struct ncr53c9x_softc *sc);
static int esp_dma_isactive(struct ncr53c9x_softc *sc);
static int espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep);
static int espattach(struct esp_softc *esc,
const struct ncr53c9x_glue *gluep);
static int espdetach(struct esp_softc *esc);
static struct ncr53c9x_glue esp_sbus_glue = {
static const struct ncr53c9x_glue esp_sbus_glue = {
esp_read_reg,
esp_write_reg,
esp_dma_isintr,
@ -209,29 +208,16 @@ esp_sbus_attach(device_t dev)
struct ncr53c9x_softc *sc;
struct lsi64854_softc *lsc;
device_t *children;
const char *name;
phandle_t node;
int burst, error, i, nchildren, slot;
int error, i, nchildren;
esc = device_get_softc(dev);
bzero(esc, sizeof(struct esp_softc));
sc = &esc->sc_ncr53c9x;
lsc = NULL;
esc->sc_dev = dev;
name = ofw_bus_get_name(dev);
node = ofw_bus_get_node(dev);
if (OF_getprop(node, "initiator-id", &sc->sc_id,
sizeof(sc->sc_id)) == -1)
sc->sc_id = 7;
sc->sc_freq = sbus_get_clockfreq(dev);
#ifdef ESP_SBUS_DEBUG
device_printf(dev, "%s: sc_id %d, freq %d\n", __func__, sc->sc_id,
sc->sc_freq);
#endif
if (strcmp(name, "SUNW,fas") == 0) {
if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") == 0) {
/*
* Allocate space for DMA, in SUNW,fas there are no
* separate DMA devices.
@ -250,20 +236,18 @@ esp_sbus_attach(device_t dev)
*/
/* Allocate DMA registers. */
lsc->sc_rid = 0;
i = 0;
if ((lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&lsc->sc_rid, RF_ACTIVE)) == NULL) {
&i, RF_ACTIVE)) == NULL) {
device_printf(dev, "cannot allocate DMA registers\n");
error = ENXIO;
goto fail_sbus_lsc;
}
lsc->sc_regt = rman_get_bustag(lsc->sc_res);
lsc->sc_regh = rman_get_bushandle(lsc->sc_res);
/* Create a parent DMA tag based on this bus. */
error = bus_dma_tag_create(
bus_get_dma_tag(dev), /* parent */
PAGE_SIZE, 0, /* alignment, boundary */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
@ -277,38 +261,31 @@ esp_sbus_attach(device_t dev)
device_printf(dev, "cannot allocate parent DMA tag\n");
goto fail_sbus_lres;
}
burst = sbus_get_burstsz(dev);
i = sbus_get_burstsz(dev);
#ifdef ESP_SBUS_DEBUG
printf("%s: burst 0x%x\n", __func__, burst);
printf("%s: burst 0x%x\n", __func__, i);
#endif
lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
(burst & SBUS_BURST_16) ? 16 : 0;
lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
(i & SBUS_BURST_16) ? 16 : 0;
lsc->sc_channel = L64854_CHANNEL_SCSI;
lsc->sc_client = sc;
lsc->sc_dev = dev;
error = lsi64854_attach(lsc);
if (error != 0) {
device_printf(dev, "lsi64854_attach failed\n");
goto fail_sbus_lpdma;
}
/*
* Allocate SCSI core registers.
*/
esc->sc_rid = 1;
i = 1;
if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&esc->sc_rid, RF_ACTIVE)) == NULL) {
&i, RF_ACTIVE)) == NULL) {
device_printf(dev,
"cannot allocate SCSI core registers\n");
error = ENXIO;
goto fail_sbus_lsi;
goto fail_sbus_lpdma;
}
esc->sc_regt = rman_get_bustag(esc->sc_res);
esc->sc_regh = rman_get_bushandle(esc->sc_res);
} else {
/*
* Search accompanying DMA engine. It should have been
@ -319,10 +296,9 @@ esp_sbus_attach(device_t dev)
device_printf(dev, "cannot determine siblings\n");
return (ENXIO);
}
slot = sbus_get_slot(dev);
for (i = 0; i < nchildren; i++) {
if (device_is_attached(children[i]) &&
sbus_get_slot(children[i]) == slot &&
sbus_get_slot(children[i]) == sbus_get_slot(dev) &&
strcmp(ofw_bus_get_name(children[i]), "dma") == 0) {
/* XXX hackery */
esc->sc_dma = (struct lsi64854_softc *)
@ -340,15 +316,13 @@ esp_sbus_attach(device_t dev)
/*
* Allocate SCSI core registers.
*/
esc->sc_rid = 0;
i = 0;
if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&esc->sc_rid, RF_ACTIVE)) == NULL) {
&i, RF_ACTIVE)) == NULL) {
device_printf(dev,
"cannot allocate SCSI core registers\n");
return (ENXIO);
}
esc->sc_regt = rman_get_bustag(esc->sc_res);
esc->sc_regh = rman_get_bushandle(esc->sc_res);
}
error = espattach(esc, &esp_sbus_glue);
@ -360,15 +334,15 @@ esp_sbus_attach(device_t dev)
return (0);
fail_sbus_eres:
bus_release_resource(dev, SYS_RES_MEMORY, esc->sc_rid, esc->sc_res);
if (strcmp(name, "SUNW,fas") != 0)
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
esc->sc_res);
if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0)
return (error);
fail_sbus_lsi:
lsi64854_detach(lsc);
fail_sbus_lpdma:
bus_dma_tag_destroy(lsc->sc_parent_dmat);
fail_sbus_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);
fail_sbus_lsc:
free(lsc, M_DEVBUF);
return (error);
@ -378,28 +352,22 @@ static int
esp_sbus_detach(device_t dev)
{
struct esp_softc *esc;
struct ncr53c9x_softc *sc;
struct lsi64854_softc *lsc;
int error;
esc = device_get_softc(dev);
sc = &esc->sc_ncr53c9x;
lsc = esc->sc_dma;
bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
error = ncr53c9x_detach(sc);
error = espdetach(esc);
if (error != 0)
return (error);
bus_release_resource(esc->sc_dev, SYS_RES_IRQ, esc->sc_irqrid,
esc->sc_irqres);
bus_release_resource(dev, SYS_RES_MEMORY, esc->sc_rid, esc->sc_res);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
esc->sc_res);
if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0)
return (0);
error = lsi64854_detach(lsc);
if (error != 0)
return (error);
bus_dma_tag_destroy(lsc->sc_parent_dmat);
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);
free(lsc, M_DEVBUF);
return (0);
@ -410,29 +378,18 @@ esp_dma_attach(device_t dev)
{
struct esp_softc *esc;
struct ncr53c9x_softc *sc;
phandle_t node;
int error;
int error, i;
esc = device_get_softc(dev);
bzero(esc, sizeof(struct esp_softc));
sc = &esc->sc_ncr53c9x;
esc->sc_dev = dev;
node = ofw_bus_get_node(dev);
if (OF_getprop(node, "initiator-id", &sc->sc_id,
sizeof(sc->sc_id)) == -1)
sc->sc_id = 7;
if (OF_getprop(node, "clock-frequency", &sc->sc_freq,
sizeof(sc->sc_freq)) == -1) {
if (OF_getprop(ofw_bus_get_node(dev), "clock-frequency",
&sc->sc_freq, sizeof(sc->sc_freq)) == -1) {
printf("failed to query OFW for clock-frequency\n");
return (ENXIO);
}
#ifdef ESP_SBUS_DEBUG
device_printf(dev, "%s: sc_id %d, freq %d\n", __func__, sc->sc_id,
sc->sc_freq);
#endif
/* XXX hackery */
esc->sc_dma = (struct lsi64854_softc *)
device_get_softc(device_get_parent(dev));
@ -441,14 +398,12 @@ esp_dma_attach(device_t dev)
/*
* Allocate SCSI core registers.
*/
esc->sc_rid = 0;
i = 0;
if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&esc->sc_rid, RF_ACTIVE)) == NULL) {
&i, RF_ACTIVE)) == NULL) {
device_printf(dev, "cannot allocate SCSI core registers\n");
return (ENXIO);
}
esc->sc_regt = rman_get_bustag(esc->sc_res);
esc->sc_regh = rman_get_bushandle(esc->sc_res);
error = espattach(esc, &esp_sbus_glue);
if (error != 0) {
@ -459,7 +414,8 @@ esp_dma_attach(device_t dev)
return (0);
fail_dma_eres:
bus_release_resource(dev, SYS_RES_MEMORY, esc->sc_rid, esc->sc_res);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
esc->sc_res);
return (error);
}
@ -467,19 +423,15 @@ static int
esp_dma_detach(device_t dev)
{
struct esp_softc *esc;
struct ncr53c9x_softc *sc;
int error;
esc = device_get_softc(dev);
sc = &esc->sc_ncr53c9x;
bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
error = ncr53c9x_detach(sc);
error = espdetach(esc);
if (error != 0)
return (error);
bus_release_resource(esc->sc_dev, SYS_RES_IRQ, esc->sc_irqrid,
esc->sc_irqres);
bus_release_resource(dev, SYS_RES_MEMORY, esc->sc_rid, esc->sc_res);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
esc->sc_res);
return (0);
}
@ -499,11 +451,29 @@ esp_resume(device_t dev)
}
static int
espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep)
{
struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
unsigned int uid = 0;
int error;
int error, i;
NCR_LOCK_INIT(sc);
/* Attach the DMA engine. */
error = lsi64854_attach(esc->sc_dma);
if (error != 0) {
device_printf(esc->sc_dev, "lsi64854_attach failed\n");
goto fail_lock;
}
if (OF_getprop(ofw_bus_get_node(esc->sc_dev), "scsi-initiator-id",
&sc->sc_id, sizeof(sc->sc_id)) == -1)
sc->sc_id = 7;
#ifdef ESP_SBUS_DEBUG
device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n",
__func__, sc->sc_id, sc->sc_freq);
#endif
/*
* The `ESC' DMA chip must be reset before we can access
@ -598,7 +568,7 @@ espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
*/
device_printf(esc->sc_dev,
"Unknown chip\n");
return (ENXIO);
goto fail_lsi;
}
}
}
@ -635,20 +605,20 @@ espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
*/
switch (sc->sc_rev) {
case NCR_VARIANT_ESP100:
sc->sc_maxwidth = 0;
sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
sc->sc_maxxfer = 64 * 1024;
sc->sc_minsync = 0; /* No synch on old chip? */
break;
case NCR_VARIANT_ESP100A:
sc->sc_maxwidth = 0;
sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
sc->sc_maxxfer = 64 * 1024;
/* Min clocks/byte is 5 */
sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
break;
case NCR_VARIANT_ESP200:
sc->sc_maxwidth = 0;
sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
sc->sc_maxxfer = 16 * 1024 * 1024;
/* Min clocks/byte is 5 */
sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
@ -670,28 +640,26 @@ espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
sc->sc_features = NCR_F_FASTSCSI;
sc->sc_cfg3 = NCRF9XCFG3_FCLK;
sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI;
sc->sc_maxwidth = 0;
sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
sc->sc_maxxfer = 16 * 1024 * 1024;
break;
case NCR_VARIANT_FAS366:
sc->sc_maxwidth = 1;
sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT;
sc->sc_maxxfer = 16 * 1024 * 1024;
break;
}
/* Limit minsync due to unsolved performance issues. */
sc->sc_maxsync = sc->sc_minsync;
/* Establish interrupt channel. */
esc->sc_irqrid = 0;
i = 0;
if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ,
&esc->sc_irqrid, RF_SHAREABLE|RF_ACTIVE)) == NULL) {
&i, RF_SHAREABLE|RF_ACTIVE)) == NULL) {
device_printf(esc->sc_dev, "cannot allocate interrupt\n");
return (ENXIO);
goto fail_lsi;
}
if (bus_setup_intr(esc->sc_dev, esc->sc_irqres,
INTR_TYPE_BIO, NULL, ncr53c9x_intr, sc, &esc->sc_irq)) {
INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc,
&esc->sc_irq)) {
device_printf(esc->sc_dev, "cannot set up interrupt\n");
error = ENXIO;
goto fail_ires;
@ -714,19 +682,43 @@ espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
fail_intr:
bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
fail_ires:
bus_release_resource(esc->sc_dev, SYS_RES_IRQ, esc->sc_irqrid,
esc->sc_irqres);
bus_release_resource(esc->sc_dev, SYS_RES_IRQ,
rman_get_rid(esc->sc_irqres), esc->sc_irqres);
fail_lsi:
lsi64854_detach(esc->sc_dma);
fail_lock:
NCR_LOCK_DESTROY(sc);
return (error);
}
static int
espdetach(struct esp_softc *esc)
{
struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
int error;
bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
error = ncr53c9x_detach(sc);
if (error != 0)
return (error);
error = lsi64854_detach(esc->sc_dma);
if (error != 0)
return (error);
NCR_LOCK_DESTROY(sc);
bus_release_resource(esc->sc_dev, SYS_RES_IRQ,
rman_get_rid(esc->sc_irqres), esc->sc_irqres);
return (0);
}
/*
* Glue functions
*/
#ifdef ESP_SBUS_DEBUG
int esp_sbus_debug = 0;
static int esp_sbus_debug = 0;
static struct {
static const struct {
char *r_name;
int r_flag;
} esp__read_regnames [] = {
@ -748,7 +740,7 @@ static struct {
{ "TCX", 1}, /* f/3c */
};
static struct {
static const struct {
char *r_name;
int r_flag;
} esp__write_regnames[] = {
@ -777,13 +769,15 @@ esp_read_reg(struct ncr53c9x_softc *sc, int reg)
struct esp_softc *esc = (struct esp_softc *)sc;
u_char v;
v = bus_space_read_1(esc->sc_regt, esc->sc_regh, reg * 4);
v = bus_read_1(esc->sc_res, reg * 4);
#ifdef ESP_SBUS_DEBUG
if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
printf("RD:%x <%s> %x\n", reg * 4,
((unsigned)reg < 0x10) ? esp__read_regnames[reg].r_name : "<***>", v);
printf("RD:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ?
esp__read_regnames[reg].r_name : "<***>", v);
#endif
return v;
return (v);
}
static void
@ -793,10 +787,11 @@ esp_write_reg(struct ncr53c9x_softc *sc, int reg, u_char v)
#ifdef ESP_SBUS_DEBUG
if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
printf("WR:%x <%s> %x\n", reg * 4,
((unsigned)reg < 0x10) ? esp__write_regnames[reg].r_name : "<***>", v);
printf("WR:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ?
esp__write_regnames[reg].r_name : "<***>", v);
#endif
bus_space_write_1(esc->sc_regt, esc->sc_regh, reg * 4, v);
bus_write_1(esc->sc_res, reg * 4, v);
}
static int

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */
@ -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 */
@ -180,6 +181,12 @@ 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 */
@ -187,18 +194,13 @@ struct ncr53c9x_tinfo {
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 */
};
@ -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 */
@ -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 */
@ -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 */
@ -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
*/
@ -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))
/*
@ -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_ */

View File

@ -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;
@ -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);
/*
@ -142,10 +139,9 @@ 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
@ -153,10 +149,9 @@ 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
@ -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);
@ -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;
@ -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 */
@ -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,
@ -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;
}
@ -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);
@ -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;
@ -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);

View File

@ -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>
@ -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;
@ -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;
@ -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);
@ -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);
}

View File

@ -70,9 +70,9 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/resource.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/rman.h>
#include <machine/bus.h>
@ -112,7 +112,7 @@ static int lsi64854_pp_intr(void *);
/*
* Finish attaching this DMA device.
* Front-end must fill in these fields:
* sc_regs
* sc_res
* sc_burst
* sc_channel (one of SCSI, ENET, PP)
* sc_client (one of SCSI, ENET, PP `soft_c' pointers)
@ -120,12 +120,24 @@ static int lsi64854_pp_intr(void *);
int
lsi64854_attach(struct lsi64854_softc *sc)
{
bus_dma_lock_t *lockfunc;
struct ncr53c9x_softc *nsc;
void *lockfuncarg;
uint32_t csr;
int error;
/* Indirect functions */
lockfunc = NULL;
lockfuncarg = NULL;
switch (sc->sc_channel) {
case L64854_CHANNEL_SCSI:
nsc = sc->sc_client;
if (NCR_LOCK_INITIALIZED(nsc) == 0) {
device_printf(sc->sc_dev, "mutex not initialized\n");
return (ENXIO);
}
lockfunc = busdma_lock_mutex;
lockfuncarg = &nsc->sc_lock;
sc->intr = lsi64854_scsi_intr;
sc->setup = lsi64854_setup;
break;
@ -141,29 +153,32 @@ lsi64854_attach(struct lsi64854_softc *sc)
}
sc->reset = lsi64854_reset;
/* Allocate a dmamap */
error = bus_dma_tag_create(
sc->sc_parent_dmat, /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MAX_DMA_SZ, /* maxsize */
1, /* nsegments */
MAX_DMA_SZ, /* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->sc_buffer_dmat);
if (error != 0) {
device_printf(sc->sc_dev, "cannot allocate buffer DMA tag\n");
return (error);
}
if (sc->setup != NULL) {
error = bus_dma_tag_create(
sc->sc_parent_dmat, /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MAX_DMA_SZ, /* maxsize */
1, /* nsegments */
MAX_DMA_SZ, /* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
lockfunc, lockfuncarg, /* lockfunc, lockfuncarg */
&sc->sc_buffer_dmat);
if (error != 0) {
device_printf(sc->sc_dev,
"cannot allocate buffer DMA tag\n");
return (error);
}
error = bus_dmamap_create(sc->sc_buffer_dmat, 0, &sc->sc_dmamap);
if (error != 0) {
device_printf(sc->sc_dev, "DMA map create failed\n");
bus_dma_tag_destroy(sc->sc_buffer_dmat);
return (error);
error = bus_dmamap_create(sc->sc_buffer_dmat, 0,
&sc->sc_dmamap);
if (error != 0) {
device_printf(sc->sc_dev, "DMA map create failed\n");
bus_dma_tag_destroy(sc->sc_buffer_dmat);
return (error);
}
}
csr = L64854_GCSR(sc);
@ -201,16 +216,20 @@ int
lsi64854_detach(struct lsi64854_softc *sc)
{
if (sc->setup)
if (sc->setup != NULL) {
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
(L64854_GCSR(sc) & L64854_WRITE) != 0 ?
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
bus_dmamap_destroy(sc->sc_buffer_dmat, sc->sc_dmamap);
bus_dma_tag_destroy(sc->sc_buffer_dmat);
bus_dmamap_destroy(sc->sc_buffer_dmat, sc->sc_dmamap);
bus_dma_tag_destroy(sc->sc_buffer_dmat);
}
return (0);
}
/*
* DMAWAIT waits while condition is true
* DMAWAIT waits while condition is true.
*/
#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
int count = 500000; \
@ -279,11 +298,12 @@ lsi64854_reset(struct lsi64854_softc *sc)
DPRINTF(LDB_ANY, ("%s: csr 0x%x\n", __func__, csr));
/*
* XXX is sync needed?
if (sc->sc_dmamap->dm_nsegs > 0)
if (sc->sc_dmasize != 0) {
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
(csr & D_WRITE) != 0 ? BUS_DMASYNC_PREREAD :
BUS_DMASYNC_PREWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
*/
}
if (sc->sc_rev == DMAREV_HME)
L64854_SCSR(sc, csr | D_HW_RESET_FAS366);
@ -332,7 +352,7 @@ lsi64854_reset(struct lsi64854_softc *sc)
L64854_SCSR(sc, csr);
if (sc->sc_rev == DMAREV_HME) {
bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR, 0);
bus_write_4(sc->sc_res, L64854_REG_ADDR, 0);
sc->sc_dmactl = csr;
}
sc->sc_active = 0;
@ -352,11 +372,10 @@ lsi64854_map_scsi(void *arg, bus_dma_segment_t *segs, int nseg, int error)
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
sc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR,
segs[0].ds_addr);
bus_write_4(sc->sc_res, L64854_REG_ADDR, segs[0].ds_addr);
}
#define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ-1)))
#define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ - 1)))
/*
* setup a DMA transfer
*/
@ -382,7 +401,7 @@ lsi64854_setup(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
* and we cannot cross a 16Mb boundary.
*/
*dmasize = sc->sc_dmasize =
ulmin(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
ulmin(*dmasize, DMAMAX((size_t)*sc->sc_dmaaddr));
DPRINTF(LDB_ANY, ("%s: dmasize=%ld\n", __func__, (long)sc->sc_dmasize));
@ -393,12 +412,11 @@ lsi64854_setup(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
L64854_SCSR(sc, sc->sc_dmactl | L64854_RESET);
L64854_SCSR(sc, sc->sc_dmactl);
bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_CNT,
*dmasize);
bus_write_4(sc->sc_res, L64854_REG_CNT, *dmasize);
}
/* Program the DMA address */
if (sc->sc_dmasize)
if (sc->sc_dmasize != 0)
if (bus_dmamap_load(sc->sc_buffer_dmat, sc->sc_dmamap,
*sc->sc_dmaaddr, sc->sc_dmasize, lsi64854_map_scsi, sc, 0))
panic("%s: cannot allocate DVMA address", __func__);
@ -408,8 +426,7 @@ lsi64854_setup(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
bcnt = sc->sc_dmasize;
if (((bcnt + (long)*sc->sc_dmaaddr) & PAGE_MASK_8K) != 0)
bcnt = roundup(bcnt, PAGE_SIZE_8K);
bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_CNT,
bcnt);
bus_write_4(sc->sc_res, L64854_REG_CNT, bcnt);
}
/* Setup DMA control register */
@ -447,8 +464,7 @@ lsi64854_scsi_intr(void *arg)
csr = L64854_GCSR(sc);
DPRINTF(LDB_SCSI, ("%s: addr 0x%x, csr %b\n", __func__,
bus_space_read_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR), csr,
DDMACSR_BITS));
bus_read_4(sc->sc_res, L64854_REG_ADDR), csr, DDMACSR_BITS));
if (csr & (D_ERR_PEND|D_SLAVE_ERR)) {
device_printf(sc->sc_dev, "error: csr=%b\n", csr, DDMACSR_BITS);
@ -530,14 +546,12 @@ lsi64854_scsi_intr(void *arg)
(nsc->sc_cfg2 & NCRCFG2_FE) ? NCR_READ_REG(nsc, NCR_TCH) : 0,
trans, resid));
#if 0 /* XXX */
if (sc->sc_dmamap->dm_nsegs > 0) {
if (sc->sc_dmasize != 0) {
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
(csr & D_WRITE) != 0 ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
}
#endif
*sc->sc_dmalen -= trans;
*sc->sc_dmaaddr += trans;
@ -604,11 +618,9 @@ lsi64854_map_pp(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap, sc->sc_datain ?
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR,
segs[0].ds_addr);
bus_write_4(sc->sc_res, L64854_REG_ADDR, segs[0].ds_addr);
bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_CNT,
sc->sc_dmasize);
bus_write_4(sc->sc_res, L64854_REG_CNT, sc->sc_dmasize);
}
/*
@ -635,12 +647,12 @@ lsi64854_setup_pp(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
* and we cannot cross a 16Mb boundary.
*/
*dmasize = sc->sc_dmasize =
ulmin(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
ulmin(*dmasize, DMAMAX((size_t)*sc->sc_dmaaddr));
DPRINTF(LDB_PP, ("%s: dmasize=%ld\n", __func__, (long)sc->sc_dmasize));
/* Program the DMA address */
if (sc->sc_dmasize)
if (sc->sc_dmasize != 0)
if (bus_dmamap_load(sc->sc_buffer_dmat, sc->sc_dmamap,
*sc->sc_dmaaddr, sc->sc_dmasize, lsi64854_map_pp, sc, 0))
panic("%s: pp cannot allocate DVMA address", __func__);
@ -680,12 +692,10 @@ lsi64854_pp_intr(void *arg)
csr = L64854_GCSR(sc);
DPRINTF(LDB_PP, ("%s: addr 0x%x, csr %b\n", __func__,
bus_space_read_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR), csr,
PDMACSR_BITS));
bus_read_4(sc->sc_res, L64854_REG_ADDR), csr, PDMACSR_BITS));
if (csr & (P_ERR_PEND|P_SLAVE_ERR)) {
resid = bus_space_read_4(sc->sc_regt, sc->sc_regh,
L64854_REG_CNT);
resid = bus_read_4(sc->sc_res, L64854_REG_CNT);
device_printf(sc->sc_dev, "error: resid %d csr=%b\n", resid,
csr, PDMACSR_BITS);
csr &= ~P_EN_DMA; /* Stop DMA */
@ -699,8 +709,7 @@ lsi64854_pp_intr(void *arg)
if (sc->sc_active != 0) {
DMA_DRAIN(sc, 0);
resid = bus_space_read_4(sc->sc_regt, sc->sc_regh,
L64854_REG_CNT);
resid = bus_read_4(sc->sc_res, L64854_REG_CNT);
}
/* DMA has stopped */
@ -714,14 +723,12 @@ lsi64854_pp_intr(void *arg)
*sc->sc_dmalen -= trans;
*sc->sc_dmaaddr += trans;
#if 0 /* XXX */
if (sc->sc_dmamap->dm_nsegs > 0) {
if (sc->sc_dmasize != 0) {
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
(csr & D_WRITE) != 0 ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
}
#endif
return (ret != 0);
}

View File

@ -41,10 +41,7 @@
struct lsi64854_softc {
device_t sc_dev;
int sc_rid;
struct resource *sc_res;
bus_space_handle_t sc_regh;
bus_space_tag_t sc_regt;
u_int sc_rev; /* revision */
int sc_burst; /* max suported burst size */
@ -54,7 +51,7 @@ struct lsi64854_softc {
#define L64854_CHANNEL_PP 3
void *sc_client;
int sc_active; /* DMA active ? */
int sc_active; /* DMA active? */
bus_dmamap_t sc_dmamap; /* DMA map for bus_dma_* */
bus_dma_tag_t sc_parent_dmat;
@ -73,12 +70,8 @@ struct lsi64854_softc {
int sc_dodrain;
};
#define L64854_GCSR(sc) \
(bus_space_read_4((sc)->sc_regt, (sc)->sc_regh, L64854_REG_CSR))
#define L64854_SCSR(sc, csr) \
bus_space_write_4((sc)->sc_regt, (sc)->sc_regh, L64854_REG_CSR, csr)
#define L64854_GCSR(sc) bus_read_4((sc)->sc_res, L64854_REG_CSR)
#define L64854_SCSR(sc, csr) bus_write_4((sc)->sc_res, L64854_REG_CSR, csr)
/*
* DMA engine interface functions.
@ -86,7 +79,6 @@ struct lsi64854_softc {
#define DMA_RESET(sc) (((sc)->reset)(sc))
#define DMA_INTR(sc) (((sc)->intr)(sc))
#define DMA_SETUP(sc, a, l, d, s) (((sc)->setup)(sc, a, l, d, s))
#define DMA_ISACTIVE(sc) ((sc)->sc_active)
#define DMA_ENINTR(sc) do { \
@ -104,6 +96,5 @@ struct lsi64854_softc {
sc->sc_active = 1; \
} while (0)
int lsi64854_attach(struct lsi64854_softc *);
int lsi64854_detach(struct lsi64854_softc *);