- Perform all necessary bus_dmamap_sync() operations.

- Greatly simplify allocation and DMA mapping of the mailbox and ccbs.
- Be more robust against resource shortage errors, and report errors better.
This commit is contained in:
thorpej 1998-02-17 03:02:30 +00:00
parent 7cfc52b208
commit 4399060ec9
7 changed files with 240 additions and 217 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ahb.c,v 1.17 1998/02/04 05:13:39 thorpej Exp $ */
/* $NetBSD: ahb.c,v 1.18 1998/02/17 03:02:30 thorpej Exp $ */
#undef AHBDEBUG
#ifdef DDB
@ -131,6 +131,9 @@ struct ahb_softc {
bus_dma_tag_t sc_dmat;
void *sc_ih;
bus_dmamap_t sc_dmamap_ecb; /* maps the ecbs */
struct ahb_ecb *sc_ecbs; /* all our ecbs */
struct ahb_ecb *sc_ecbhash[ECB_HASH_SIZE];
TAILQ_HEAD(, ahb_ecb) sc_free_ecb;
struct ahb_ecb *sc_immed_ecb; /* an outstanding immediete command */
@ -141,6 +144,11 @@ struct ahb_softc {
struct scsipi_xfer *sc_queuelast;
};
/*
* Offset of an ECB from the beginning of the ECB DMA mapping.
*/
#define AHB_ECB_OFF(e) (((u_long)(e)) - ((u_long)&sc->sc_ecbs[0]))
struct ahb_probe_data {
int sc_irq;
int sc_scsi_dev;
@ -154,12 +162,12 @@ struct ahb_ecb *ahb_get_ecb __P((struct ahb_softc *, int));
struct ahb_ecb *ahb_ecb_phys_kv __P((struct ahb_softc *, physaddr));
void ahb_done __P((struct ahb_softc *, struct ahb_ecb *));
int ahb_find __P((bus_space_tag_t, bus_space_handle_t, struct ahb_probe_data *));
void ahb_init __P((struct ahb_softc *));
int ahb_init __P((struct ahb_softc *));
void ahbminphys __P((struct buf *));
int ahb_scsi_cmd __P((struct scsipi_xfer *));
int ahb_poll __P((struct ahb_softc *, struct scsipi_xfer *, int));
void ahb_timeout __P((void *));
int ahb_create_ecbs __P((struct ahb_softc *));
int ahb_create_ecbs __P((struct ahb_softc *, struct ahb_ecb *, int));
void ahb_enqueue __P((struct ahb_softc *, struct scsipi_xfer *, int));
struct scsipi_xfer *ahb_dequeue __P((struct ahb_softc *));
@ -271,10 +279,14 @@ ahbattach(parent, self, aux)
if (ahb_find(iot, ioh, &apd))
panic("ahbattach: ahb_find failed!");
ahb_init(sc);
TAILQ_INIT(&sc->sc_free_ecb);
LIST_INIT(&sc->sc_queue);
if (ahb_init(sc) != 0) {
/* Error during initialization! */
return;
}
/*
* fill in the prototype scsipi_link.
*/
@ -383,7 +395,7 @@ ahb_send_mbox(sc, opcode, ecb)
* XXX WHAT DOES THIS COMMENT MEAN?! --thorpej
*/
bus_space_write_4(iot, ioh, MBOXOUT0,
ecb->dmamap_self->dm_segs[0].ds_addr);
sc->sc_dmamap_ecb->dm_segs[0].ds_addr + AHB_ECB_OFF(ecb));
bus_space_write_1(iot, ioh, ATTN, opcode |
ecb->xs->sc_link->scsipi_scsi.target);
@ -546,23 +558,8 @@ ahb_init_ecb(sc, ecb)
int hashnum, error;
/*
* XXX Should we put a DIAGNOSTIC check for multiple
* XXX ECB inits here?
* Create the DMA map for this ECB.
*/
bzero(ecb, sizeof(struct ahb_ecb));
/*
* Create the DMA maps for this ECB.
*/
error = bus_dmamap_create(dmat, sizeof(struct ahb_ecb), 1,
sizeof(struct ahb_ecb), 0, BUS_DMA_NOWAIT, &ecb->dmamap_self);
if (error) {
printf("%s: can't create ecb dmamap_self\n",
sc->sc_dev.dv_xname);
return (error);
}
error = bus_dmamap_create(dmat, AHB_MAXXFER, AHB_NSEG, AHB_MAXXFER,
0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ecb->dmamap_xfer);
if (error) {
@ -571,24 +568,12 @@ ahb_init_ecb(sc, ecb)
return (error);
}
/*
* Load the permanent DMA maps.
*/
error = bus_dmamap_load(dmat, ecb->dmamap_self, ecb,
sizeof(struct ahb_ecb), NULL, BUS_DMA_NOWAIT);
if (error) {
printf("%s: can't load ecb dmamap_self\n",
sc->sc_dev.dv_xname);
bus_dmamap_destroy(dmat, ecb->dmamap_self);
bus_dmamap_destroy(dmat, ecb->dmamap_xfer);
return (error);
}
/*
* put in the phystokv hash table
* Never gets taken out.
*/
ecb->hashkey = ecb->dmamap_self->dm_segs[0].ds_addr;
ecb->hashkey = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
AHB_ECB_OFF(ecb);
hashnum = ECB_HASH(ecb->hashkey);
ecb->nexthash = sc->sc_ecbhash[hashnum];
sc->sc_ecbhash[hashnum] = ecb;
@ -597,47 +582,26 @@ ahb_init_ecb(sc, ecb)
}
int
ahb_create_ecbs(sc)
ahb_create_ecbs(sc, ecbstore, count)
struct ahb_softc *sc;
struct ahb_ecb *ecbstore;
int count;
{
bus_dma_segment_t seg;
bus_size_t size;
struct ahb_ecb *ecb;
int rseg, error;
int i, error;
size = NBPG;
error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, &rseg,
BUS_DMA_NOWAIT);
if (error) {
printf("%s: can't allocate memory for ecbs\n",
sc->sc_dev.dv_xname);
return (error);
}
error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
(caddr_t *)&ecb, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
if (error) {
printf("%s: can't map memory for ecbs\n",
sc->sc_dev.dv_xname);
bus_dmamem_free(sc->sc_dmat, &seg, rseg);
return (error);
}
bzero(ecb, size);
while (size > sizeof(struct ahb_ecb)) {
error = ahb_init_ecb(sc, ecb);
if (error) {
printf("%s: can't initialize ecb\n",
sc->sc_dev.dv_xname);
return (error);
bzero(ecbstore, sizeof(struct ahb_ecb) * count);
for (i = 0; i < count; i++) {
ecb = &ecbstore[i];
if ((error = ahb_init_ecb(sc, ecb)) != 0) {
printf("%s: unable to initialize ecb, error = %d\n",
sc->sc_dev.dv_xname, error);
goto out;
}
TAILQ_INSERT_TAIL(&sc->sc_free_ecb, ecb, chain);
(caddr_t)ecb += ALIGN(sizeof(struct ahb_ecb));
size -= ALIGN(sizeof(struct ahb_ecb));
sc->sc_numecbs++;
}
return (0);
out:
return (i);
}
/*
@ -666,20 +630,6 @@ ahb_get_ecb(sc, flags)
TAILQ_REMOVE(&sc->sc_free_ecb, ecb, chain);
break;
}
if (sc->sc_numecbs < AHB_ECB_MAX) {
/*
* ahb_create_ecbs() might have managed to create
* one before it failed. If so, don't abort,
* just grab it and continue to hobble along.
*/
if (ahb_create_ecbs(sc) != 0 &&
sc->sc_free_ecb.tqh_first == NULL) {
printf("%s: can't allocate ecbs\n",
sc->sc_dev.dv_xname);
goto out;
}
continue;
}
if ((flags & SCSI_NOSLEEP) != 0)
goto out;
tsleep(&sc->sc_free_ecb, PRIBIO, "ahbecb", 0);
@ -726,6 +676,10 @@ ahb_done(sc, ecb)
SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahb_done\n"));
bus_dmamap_sync(dmat, sc->sc_dmamap_ecb,
AHB_ECB_OFF(ecb), sizeof(struct ahb_ecb),
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
/*
* If we were a data transfer, unload the map that described
* the data buffer.
@ -892,11 +846,64 @@ ahb_find(iot, ioh, sc)
return 0;
}
void
int
ahb_init(sc)
struct ahb_softc *sc;
{
bus_dma_segment_t seg;
int i, error, rseg;
#define ECBSIZE (AHB_ECB_MAX * sizeof(struct ahb_ecb))
/*
* Allocate the ECBs.
*/
if ((error = bus_dmamem_alloc(sc->sc_dmat, ECBSIZE,
NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
printf("%s: unable to allocate ecbs, error = %d\n",
sc->sc_dev.dv_xname, error);
return (error);
}
if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
ECBSIZE, (caddr_t *)&sc->sc_ecbs,
BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
printf("%s: unable to map ecbs, error = %d\n",
sc->sc_dev.dv_xname, error);
return (error);
}
/*
* Create and load the DMA map used for the ecbs.
*/
if ((error = bus_dmamap_create(sc->sc_dmat, ECBSIZE,
1, ECBSIZE, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap_ecb)) != 0) {
printf("%s: unable to create ecb DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return (error);
}
if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ecb,
sc->sc_ecbs, ECBSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
printf("%s: unable to load ecb DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return (error);
}
#undef ECBSIZE
/*
* Initialize the ecbs.
*/
i = ahb_create_ecbs(sc, sc->sc_ecbs, AHB_ECB_MAX);
if (i == 0) {
printf("%s: unable to create ecbs\n",
sc->sc_dev.dv_xname);
return (ENOMEM);
} else if (i != AHB_ECB_MAX) {
printf("%s: WARNING: only %d of %d ecbs created\n",
sc->sc_dev.dv_xname, i, AHB_ECB_MAX);
}
return (0);
}
void
@ -1028,11 +1035,11 @@ ahb_scsi_cmd(xs)
ecb->opt1 = ECB_SES /*| ECB_DSB*/ | ECB_ARS;
ecb->opt2 = sc_link->scsipi_scsi.lun | ECB_NRB;
bcopy(xs->cmd, &ecb->scsi_cmd, ecb->scsi_cmd_length = xs->cmdlen);
ecb->sense_ptr = ecb->dmamap_self->dm_segs[0].ds_addr +
offsetof(struct ahb_ecb, ecb_sense);
ecb->sense_ptr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_sense);
ecb->req_sense_length = sizeof(ecb->ecb_sense);
ecb->status = ecb->dmamap_self->dm_segs[0].ds_addr +
offsetof(struct ahb_ecb, ecb_status);
ecb->status = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_status);
ecb->ecb_status.host_stat = 0x00;
ecb->ecb_status.target_stat = 0x00;
@ -1084,8 +1091,8 @@ ahb_scsi_cmd(xs)
ecb->dmamap_xfer->dm_segs[seg].ds_len;
}
ecb->data_addr = ecb->dmamap_self->dm_segs[0].ds_addr +
offsetof(struct ahb_ecb, ahb_dma);
ecb->data_addr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ahb_dma);
ecb->data_length = ecb->dmamap_xfer->dm_nsegs *
sizeof(struct ahb_dma_seg);
ecb->opt1 |= ECB_S_G;
@ -1095,6 +1102,10 @@ ahb_scsi_cmd(xs)
}
ecb->link_addr = (physaddr)0;
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ecb,
AHB_ECB_OFF(ecb), sizeof(struct ahb_ecb),
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
s = splbio();
ahb_send_mbox(sc, OP_START_ECB, ecb);
splx(s);

View File

@ -1,7 +1,7 @@
/* $NetBSD: ahbreg.h,v 1.4 1997/08/27 11:24:41 bouyer Exp $ */
/* $NetBSD: ahbreg.h,v 1.5 1998/02/17 03:02:30 thorpej Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -253,17 +253,6 @@ struct ahb_ecb {
#define ECB_IMMED_FAIL 0x08
int timeout;
/*
* DMA maps used by the ECB. These maps are created
* in ahb_init_ecb().
*/
/*
* This DMA map maps an individual ECB. This map is
* permanently loaded in ahb_init_ecb().
*/
bus_dmamap_t dmamap_self;
/*
* This DMA map maps the buffer involved in the transfer.
* Its contents are loaded into "ahb_dma" above.

View File

@ -1,4 +1,4 @@
/* $NetBSD: uha_eisa.c,v 1.9 1997/08/27 11:24:44 bouyer Exp $ */
/* $NetBSD: uha_eisa.c,v 1.10 1998/02/17 03:02:56 thorpej Exp $ */
/*
* Copyright (c) 1994, 1996, 1997 Charles M. Hannum. All rights reserved.
@ -253,7 +253,7 @@ u24_start_mbox(sc, mscp)
}
bus_space_write_4(iot, ioh, U24_OGMPTR,
mscp->dmamap_self->dm_segs[0].ds_addr);
sc->sc_dmamap_mscp->dm_segs[0].ds_addr + UHA_MSCP_OFF(mscp));
if (mscp->flags & MSCP_ABORT)
bus_space_write_1(iot, ioh, U24_OGMCMD, 0x80);
else

View File

@ -1,4 +1,4 @@
/* $NetBSD: uha.c,v 1.15 1998/02/04 05:14:02 thorpej Exp $ */
/* $NetBSD: uha.c,v 1.16 1998/02/17 03:02:56 thorpej Exp $ */
#undef UHADEBUG
#ifdef DDB
@ -129,7 +129,7 @@ integrate int uha_init_mscp __P((struct uha_softc *, struct uha_mscp *));
struct uha_mscp *uha_get_mscp __P((struct uha_softc *, int));
void uhaminphys __P((struct buf *));
int uha_scsi_cmd __P((struct scsipi_xfer *));
int uha_create_mscps __P((struct uha_softc *, void *, size_t));
int uha_create_mscps __P((struct uha_softc *, struct uha_mscp *, int));
void uha_enqueue __P((struct uha_softc *, struct scsipi_xfer *, int));
struct scsipi_xfer *uha_dequeue __P((struct uha_softc *));
@ -199,6 +199,8 @@ uha_attach(sc, upd)
struct uha_softc *sc;
struct uha_probe_data *upd;
{
bus_dma_segment_t seg;
int i, error, rseg;
TAILQ_INIT(&sc->sc_free_mscp);
LIST_INIT(&sc->sc_queue);
@ -217,6 +219,57 @@ uha_attach(sc, upd)
sc->sc_link.scsipi_scsi.max_target = 7;
sc->sc_link.type = BUS_SCSI;
#define MSCPSIZE (UHA_MSCP_MAX * sizeof(struct uha_mscp))
/*
* Allocate the MSCPs.
*/
if ((error = bus_dmamem_alloc(sc->sc_dmat, MSCPSIZE,
NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
printf("%s: unable to allocate mscps, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
MSCPSIZE, (caddr_t *)&sc->sc_mscps,
BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
printf("%s: unable to map mscps, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
/*
* Create and load the DMA map used for the mscps.
*/
if ((error = bus_dmamap_create(sc->sc_dmat, MSCPSIZE,
1, MSCPSIZE, 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
&sc->sc_dmamap_mscp)) != 0) {
printf("%s: unable to create mscp DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_mscp,
sc->sc_mscps, MSCPSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
printf("%s: unable to load mscp DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
#undef MSCPSIZE
/*
* Initialize the mscps.
*/
i = uha_create_mscps(sc, sc->sc_mscps, UHA_MSCP_MAX);
if (i == 0) {
printf("%s: unable to create mscps\n",
sc->sc_dev.dv_xname);
return;
} else if (i != UHA_MSCP_MAX) {
printf("%s: WARNING: only %d of %d mscps created\n",
sc->sc_dev.dv_xname, i, UHA_MSCP_MAX);
}
/*
* ask the adapter what subunits are present
*/
@ -266,43 +319,14 @@ uha_init_mscp(sc, mscp)
int hashnum, error;
/*
* XXX Should we put a DIAGNOSTIC check for multiple
* XXX MSCP inits here?
* Create the DMA map for this MSCP.
*/
bzero(mscp, sizeof(struct uha_mscp));
/*
* Create the DMA maps for this MSCP.
*/
error = bus_dmamap_create(dmat, sizeof(struct uha_mscp), 1,
sizeof(struct uha_mscp), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
&mscp->dmamap_self);
if (error) {
printf("%s: can't create mscp dmamap_self\n",
sc->sc_dev.dv_xname);
return (error);
}
error = bus_dmamap_create(dmat, UHA_MAXXFER, UHA_NSEG, UHA_MAXXFER,
0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
&mscp->dmamap_xfer);
if (error) {
printf("%s: can't create mscp dmamap_xfer\n",
sc->sc_dev.dv_xname);
return (error);
}
/*
* Load the permanent DMA maps.
*/
error = bus_dmamap_load(dmat, mscp->dmamap_self, mscp,
sizeof(struct uha_mscp), NULL, BUS_DMA_NOWAIT);
if (error) {
printf("%s: can't load mscp dmamap_self\n",
sc->sc_dev.dv_xname);
bus_dmamap_destroy(dmat, mscp->dmamap_self);
bus_dmamap_destroy(dmat, mscp->dmamap_xfer);
printf("%s: can't create mscp DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return (error);
}
@ -310,7 +334,8 @@ uha_init_mscp(sc, mscp)
* put in the phystokv hash table
* Never gets taken out.
*/
mscp->hashkey = mscp->dmamap_self->dm_segs[0].ds_addr;
mscp->hashkey = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
UHA_MSCP_OFF(mscp);
hashnum = MSCP_HASH(mscp->hashkey);
mscp->nexthash = sc->sc_mscphash[hashnum];
sc->sc_mscphash[hashnum] = mscp;
@ -322,56 +347,26 @@ uha_init_mscp(sc, mscp)
* Create a set of MSCPs and add them to the free list.
*/
int
uha_create_mscps(sc, mem, size)
uha_create_mscps(sc, mscpstore, count)
struct uha_softc *sc;
void *mem;
size_t size;
struct uha_mscp *mscpstore;
int count;
{
bus_dma_segment_t seg;
struct uha_mscp *mscp;
int rseg, error;
int i, error;
if (sc->sc_nummscps >= UHA_MSCP_MAX)
return (0);
if ((mscp = mem) != NULL)
goto have_mem;
size = NBPG;
error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, &rseg,
BUS_DMA_NOWAIT);
if (error) {
printf("%s: can't allocate memory for mscps\n",
sc->sc_dev.dv_xname);
return (error);
}
error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
(caddr_t *)&mscp, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
if (error) {
printf("%s: can't map memory for mscps\n",
sc->sc_dev.dv_xname);
bus_dmamem_free(sc->sc_dmat, &seg, rseg);
return (error);
}
have_mem:
bzero(mscp, size);
while (size > sizeof(struct uha_mscp) &&
sc->sc_nummscps < UHA_MSCP_MAX) {
error = uha_init_mscp(sc, mscp);
if (error) {
printf("%s: can't initialize mscp\n",
sc->sc_dev.dv_xname);
return (error);
bzero(mscpstore, sizeof(struct uha_mscp) * count);
for (i = 0; i < count; i++) {
mscp = &mscpstore[i];
if ((error = uha_init_mscp(sc, mscp)) != 0) {
printf("%s: unable to initialize mscp, error = %d\n",
sc->sc_dev.dv_xname, error);
goto out;
}
TAILQ_INSERT_TAIL(&sc->sc_free_mscp, mscp, chain);
(caddr_t)mscp += ALIGN(sizeof(struct uha_mscp));
size -= ALIGN(sizeof(struct uha_mscp));
sc->sc_nummscps++;
}
return (0);
out:
return (i);
}
/*
@ -400,20 +395,6 @@ uha_get_mscp(sc, flags)
TAILQ_REMOVE(&sc->sc_free_mscp, mscp, chain);
break;
}
if (sc->sc_nummscps < UHA_MSCP_MAX) {
/*
* uha_create_mscps() might have managed to create
* one before it failed. If so, don't abort,
* just grab it and continue to hobble along.
*/
if (uha_create_mscps(sc, NULL, 0) &&
sc->sc_free_mscp.tqh_first == NULL) {
printf("%s: can't allocate mscps\n",
sc->sc_dev.dv_xname);
goto out;
}
continue;
}
if ((flags & SCSI_NOSLEEP) != 0)
goto out;
tsleep(&sc->sc_free_mscp, PRIBIO, "uhamsc", 0);
@ -460,6 +441,10 @@ uha_done(sc, mscp)
SC_DEBUG(xs->sc_link, SDEV_DB2, ("uha_done\n"));
bus_dmamap_sync(dmat, sc->sc_dmamap_mscp,
UHA_MSCP_OFF(mscp), sizeof(struct uha_mscp),
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
/*
* If we were a data transfer, unload the map that described
* the data buffer.
@ -641,8 +626,8 @@ uha_scsi_cmd(xs)
mscp->target = sc_link->scsipi_scsi.target;
mscp->lun = sc_link->scsipi_scsi.lun;
mscp->scsi_cmd_length = xs->cmdlen;
mscp->sense_ptr = mscp->dmamap_self->dm_segs[0].ds_addr +
offsetof(struct uha_mscp, mscp_sense);
mscp->sense_ptr = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
UHA_MSCP_OFF(mscp) + offsetof(struct uha_mscp, mscp_sense);
mscp->req_sense_length = sizeof(mscp->mscp_sense);
mscp->host_stat = 0x00;
mscp->target_stat = 0x00;
@ -694,8 +679,8 @@ uha_scsi_cmd(xs)
mscp->dmamap_xfer->dm_segs[seg].ds_len;
}
mscp->data_addr = mscp->dmamap_self->dm_segs[0].ds_addr +
offsetof(struct uha_mscp, uha_dma);
mscp->data_addr = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
UHA_MSCP_OFF(mscp) + offsetof(struct uha_mscp, uha_dma);
mscp->data_length = xs->datalen;
mscp->sgth = 0x01;
mscp->sg_num = seg;
@ -708,6 +693,10 @@ uha_scsi_cmd(xs)
mscp->link_id = 0;
mscp->link_addr = (physaddr)0;
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_mscp,
UHA_MSCP_OFF(mscp), sizeof(struct uha_mscp),
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
s = splbio();
(sc->start_mbox)(sc, mscp);
splx(s);

View File

@ -1,7 +1,7 @@
/* $NetBSD: uhareg.h,v 1.5 1997/09/09 18:56:18 mycroft Exp $ */
/* $NetBSD: uhareg.h,v 1.6 1998/02/17 03:02:56 thorpej Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -264,17 +264,6 @@ struct uha_mscp {
#define MSCP_ABORT 0x02
int timeout;
/*
* DMA maps used by the MSCP. These maps are created
* in uha_init_mscp().
*/
/*
* This DMA map maps an individual MSCP. This map is
* permanently loaded in uha_init_mscp().
*/
bus_dmamap_t dmamap_self;
/*
* This DMA map maps the buffer involved in the transfer.
* It's contents are loaded into "uha_dma" above.

View File

@ -1,4 +1,41 @@
/* $NetBSD: uhavar.h,v 1.7 1997/11/04 05:58:30 thorpej Exp $ */
/* $NetBSD: uhavar.h,v 1.8 1998/02/17 03:02:56 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1994, 1996, 1997 Charles M. Hannum. All rights reserved.
@ -50,6 +87,9 @@ struct uha_softc {
int (*poll) __P((struct uha_softc *, struct scsipi_xfer *, int));
void (*init) __P((struct uha_softc *));
bus_dmamap_t sc_dmamap_mscp; /* maps the mscps */
struct uha_mscp *sc_mscps; /* all our mscps */
struct uha_mscp *sc_mscphash[MSCP_HASH_SIZE];
TAILQ_HEAD(, uha_mscp) sc_free_mscp;
int sc_nummscps;
@ -59,6 +99,11 @@ struct uha_softc {
struct scsipi_xfer *sc_queuelast;
};
/*
* Offset of an MSCP from the beginning of the MSCP DMA mapping.
*/
#define UHA_MSCP_OFF(m) (((u_long)(m)) - ((u_long)&sc->sc_mscps[0]))
struct uha_probe_data {
int sc_irq, sc_drq;
int sc_scsi_dev;

View File

@ -1,4 +1,4 @@
/* $NetBSD: uha_isa.c,v 1.11 1997/10/20 18:43:20 thorpej Exp $ */
/* $NetBSD: uha_isa.c,v 1.12 1998/02/17 03:02:56 thorpej Exp $ */
/*
* Copyright (c) 1994, 1996, 1997 Charles M. Hannum. All rights reserved.
@ -289,7 +289,7 @@ u14_start_mbox(sc, mscp)
}
bus_space_write_4(iot, ioh, U14_OGMPTR,
mscp->dmamap_self->dm_segs[0].ds_addr);
sc->sc_dmamap_mscp->dm_segs[0].ds_addr + UHA_MSCP_OFF(mscp));
if (mscp->flags & MSCP_ABORT)
bus_space_write_1(iot, ioh, U14_LINT, U14_ABORT);
else