- 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:
parent
7cfc52b208
commit
4399060ec9
|
@ -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
|
#undef AHBDEBUG
|
||||||
#ifdef DDB
|
#ifdef DDB
|
||||||
|
@ -131,6 +131,9 @@ struct ahb_softc {
|
||||||
bus_dma_tag_t sc_dmat;
|
bus_dma_tag_t sc_dmat;
|
||||||
void *sc_ih;
|
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];
|
struct ahb_ecb *sc_ecbhash[ECB_HASH_SIZE];
|
||||||
TAILQ_HEAD(, ahb_ecb) sc_free_ecb;
|
TAILQ_HEAD(, ahb_ecb) sc_free_ecb;
|
||||||
struct ahb_ecb *sc_immed_ecb; /* an outstanding immediete command */
|
struct ahb_ecb *sc_immed_ecb; /* an outstanding immediete command */
|
||||||
|
@ -141,6 +144,11 @@ struct ahb_softc {
|
||||||
struct scsipi_xfer *sc_queuelast;
|
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 {
|
struct ahb_probe_data {
|
||||||
int sc_irq;
|
int sc_irq;
|
||||||
int sc_scsi_dev;
|
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));
|
struct ahb_ecb *ahb_ecb_phys_kv __P((struct ahb_softc *, physaddr));
|
||||||
void ahb_done __P((struct ahb_softc *, struct ahb_ecb *));
|
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 *));
|
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 *));
|
void ahbminphys __P((struct buf *));
|
||||||
int ahb_scsi_cmd __P((struct scsipi_xfer *));
|
int ahb_scsi_cmd __P((struct scsipi_xfer *));
|
||||||
int ahb_poll __P((struct ahb_softc *, struct scsipi_xfer *, int));
|
int ahb_poll __P((struct ahb_softc *, struct scsipi_xfer *, int));
|
||||||
void ahb_timeout __P((void *));
|
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));
|
void ahb_enqueue __P((struct ahb_softc *, struct scsipi_xfer *, int));
|
||||||
struct scsipi_xfer *ahb_dequeue __P((struct ahb_softc *));
|
struct scsipi_xfer *ahb_dequeue __P((struct ahb_softc *));
|
||||||
|
|
||||||
|
@ -271,10 +279,14 @@ ahbattach(parent, self, aux)
|
||||||
if (ahb_find(iot, ioh, &apd))
|
if (ahb_find(iot, ioh, &apd))
|
||||||
panic("ahbattach: ahb_find failed!");
|
panic("ahbattach: ahb_find failed!");
|
||||||
|
|
||||||
ahb_init(sc);
|
|
||||||
TAILQ_INIT(&sc->sc_free_ecb);
|
TAILQ_INIT(&sc->sc_free_ecb);
|
||||||
LIST_INIT(&sc->sc_queue);
|
LIST_INIT(&sc->sc_queue);
|
||||||
|
|
||||||
|
if (ahb_init(sc) != 0) {
|
||||||
|
/* Error during initialization! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fill in the prototype scsipi_link.
|
* fill in the prototype scsipi_link.
|
||||||
*/
|
*/
|
||||||
|
@ -383,7 +395,7 @@ ahb_send_mbox(sc, opcode, ecb)
|
||||||
* XXX WHAT DOES THIS COMMENT MEAN?! --thorpej
|
* XXX WHAT DOES THIS COMMENT MEAN?! --thorpej
|
||||||
*/
|
*/
|
||||||
bus_space_write_4(iot, ioh, MBOXOUT0,
|
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 |
|
bus_space_write_1(iot, ioh, ATTN, opcode |
|
||||||
ecb->xs->sc_link->scsipi_scsi.target);
|
ecb->xs->sc_link->scsipi_scsi.target);
|
||||||
|
|
||||||
|
@ -546,23 +558,8 @@ ahb_init_ecb(sc, ecb)
|
||||||
int hashnum, error;
|
int hashnum, error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Should we put a DIAGNOSTIC check for multiple
|
* Create the DMA map for this ECB.
|
||||||
* XXX ECB inits here?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
error = bus_dmamap_create(dmat, AHB_MAXXFER, AHB_NSEG, AHB_MAXXFER,
|
||||||
0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ecb->dmamap_xfer);
|
0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ecb->dmamap_xfer);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -571,24 +568,12 @@ ahb_init_ecb(sc, ecb)
|
||||||
return (error);
|
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
|
* put in the phystokv hash table
|
||||||
* Never gets taken out.
|
* 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);
|
hashnum = ECB_HASH(ecb->hashkey);
|
||||||
ecb->nexthash = sc->sc_ecbhash[hashnum];
|
ecb->nexthash = sc->sc_ecbhash[hashnum];
|
||||||
sc->sc_ecbhash[hashnum] = ecb;
|
sc->sc_ecbhash[hashnum] = ecb;
|
||||||
|
@ -597,47 +582,26 @@ ahb_init_ecb(sc, ecb)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahb_create_ecbs(sc)
|
ahb_create_ecbs(sc, ecbstore, count)
|
||||||
struct ahb_softc *sc;
|
struct ahb_softc *sc;
|
||||||
|
struct ahb_ecb *ecbstore;
|
||||||
|
int count;
|
||||||
{
|
{
|
||||||
bus_dma_segment_t seg;
|
|
||||||
bus_size_t size;
|
|
||||||
struct ahb_ecb *ecb;
|
struct ahb_ecb *ecb;
|
||||||
int rseg, error;
|
int i, error;
|
||||||
|
|
||||||
size = NBPG;
|
bzero(ecbstore, sizeof(struct ahb_ecb) * count);
|
||||||
error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, &rseg,
|
for (i = 0; i < count; i++) {
|
||||||
BUS_DMA_NOWAIT);
|
ecb = &ecbstore[i];
|
||||||
if (error) {
|
if ((error = ahb_init_ecb(sc, ecb)) != 0) {
|
||||||
printf("%s: can't allocate memory for ecbs\n",
|
printf("%s: unable to initialize ecb, error = %d\n",
|
||||||
sc->sc_dev.dv_xname);
|
sc->sc_dev.dv_xname, error);
|
||||||
return (error);
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_TAIL(&sc->sc_free_ecb, ecb, chain);
|
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++;
|
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
return (0);
|
return (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -666,20 +630,6 @@ ahb_get_ecb(sc, flags)
|
||||||
TAILQ_REMOVE(&sc->sc_free_ecb, ecb, chain);
|
TAILQ_REMOVE(&sc->sc_free_ecb, ecb, chain);
|
||||||
break;
|
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)
|
if ((flags & SCSI_NOSLEEP) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
tsleep(&sc->sc_free_ecb, PRIBIO, "ahbecb", 0);
|
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"));
|
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
|
* If we were a data transfer, unload the map that described
|
||||||
* the data buffer.
|
* the data buffer.
|
||||||
|
@ -892,11 +846,64 @@ ahb_find(iot, ioh, sc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
ahb_init(sc)
|
ahb_init(sc)
|
||||||
struct ahb_softc *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
|
void
|
||||||
|
@ -1028,11 +1035,11 @@ ahb_scsi_cmd(xs)
|
||||||
ecb->opt1 = ECB_SES /*| ECB_DSB*/ | ECB_ARS;
|
ecb->opt1 = ECB_SES /*| ECB_DSB*/ | ECB_ARS;
|
||||||
ecb->opt2 = sc_link->scsipi_scsi.lun | ECB_NRB;
|
ecb->opt2 = sc_link->scsipi_scsi.lun | ECB_NRB;
|
||||||
bcopy(xs->cmd, &ecb->scsi_cmd, ecb->scsi_cmd_length = xs->cmdlen);
|
bcopy(xs->cmd, &ecb->scsi_cmd, ecb->scsi_cmd_length = xs->cmdlen);
|
||||||
ecb->sense_ptr = ecb->dmamap_self->dm_segs[0].ds_addr +
|
ecb->sense_ptr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
|
||||||
offsetof(struct ahb_ecb, ecb_sense);
|
AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_sense);
|
||||||
ecb->req_sense_length = sizeof(ecb->ecb_sense);
|
ecb->req_sense_length = sizeof(ecb->ecb_sense);
|
||||||
ecb->status = ecb->dmamap_self->dm_segs[0].ds_addr +
|
ecb->status = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
|
||||||
offsetof(struct ahb_ecb, ecb_status);
|
AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_status);
|
||||||
ecb->ecb_status.host_stat = 0x00;
|
ecb->ecb_status.host_stat = 0x00;
|
||||||
ecb->ecb_status.target_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->dmamap_xfer->dm_segs[seg].ds_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecb->data_addr = ecb->dmamap_self->dm_segs[0].ds_addr +
|
ecb->data_addr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
|
||||||
offsetof(struct ahb_ecb, ahb_dma);
|
AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ahb_dma);
|
||||||
ecb->data_length = ecb->dmamap_xfer->dm_nsegs *
|
ecb->data_length = ecb->dmamap_xfer->dm_nsegs *
|
||||||
sizeof(struct ahb_dma_seg);
|
sizeof(struct ahb_dma_seg);
|
||||||
ecb->opt1 |= ECB_S_G;
|
ecb->opt1 |= ECB_S_G;
|
||||||
|
@ -1095,6 +1102,10 @@ ahb_scsi_cmd(xs)
|
||||||
}
|
}
|
||||||
ecb->link_addr = (physaddr)0;
|
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();
|
s = splbio();
|
||||||
ahb_send_mbox(sc, OP_START_ECB, ecb);
|
ahb_send_mbox(sc, OP_START_ECB, ecb);
|
||||||
splx(s);
|
splx(s);
|
||||||
|
|
|
@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
@ -253,17 +253,6 @@ struct ahb_ecb {
|
||||||
#define ECB_IMMED_FAIL 0x08
|
#define ECB_IMMED_FAIL 0x08
|
||||||
int timeout;
|
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.
|
* This DMA map maps the buffer involved in the transfer.
|
||||||
* Its contents are loaded into "ahb_dma" above.
|
* Its contents are loaded into "ahb_dma" above.
|
||||||
|
|
|
@ -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.
|
* 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,
|
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)
|
if (mscp->flags & MSCP_ABORT)
|
||||||
bus_space_write_1(iot, ioh, U24_OGMCMD, 0x80);
|
bus_space_write_1(iot, ioh, U24_OGMCMD, 0x80);
|
||||||
else
|
else
|
||||||
|
|
181
sys/dev/ic/uha.c
181
sys/dev/ic/uha.c
|
@ -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
|
#undef UHADEBUG
|
||||||
#ifdef DDB
|
#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));
|
struct uha_mscp *uha_get_mscp __P((struct uha_softc *, int));
|
||||||
void uhaminphys __P((struct buf *));
|
void uhaminphys __P((struct buf *));
|
||||||
int uha_scsi_cmd __P((struct scsipi_xfer *));
|
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));
|
void uha_enqueue __P((struct uha_softc *, struct scsipi_xfer *, int));
|
||||||
struct scsipi_xfer *uha_dequeue __P((struct uha_softc *));
|
struct scsipi_xfer *uha_dequeue __P((struct uha_softc *));
|
||||||
|
|
||||||
|
@ -199,6 +199,8 @@ uha_attach(sc, upd)
|
||||||
struct uha_softc *sc;
|
struct uha_softc *sc;
|
||||||
struct uha_probe_data *upd;
|
struct uha_probe_data *upd;
|
||||||
{
|
{
|
||||||
|
bus_dma_segment_t seg;
|
||||||
|
int i, error, rseg;
|
||||||
|
|
||||||
TAILQ_INIT(&sc->sc_free_mscp);
|
TAILQ_INIT(&sc->sc_free_mscp);
|
||||||
LIST_INIT(&sc->sc_queue);
|
LIST_INIT(&sc->sc_queue);
|
||||||
|
@ -217,6 +219,57 @@ uha_attach(sc, upd)
|
||||||
sc->sc_link.scsipi_scsi.max_target = 7;
|
sc->sc_link.scsipi_scsi.max_target = 7;
|
||||||
sc->sc_link.type = BUS_SCSI;
|
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
|
* ask the adapter what subunits are present
|
||||||
*/
|
*/
|
||||||
|
@ -266,43 +319,14 @@ uha_init_mscp(sc, mscp)
|
||||||
int hashnum, error;
|
int hashnum, error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Should we put a DIAGNOSTIC check for multiple
|
* Create the DMA map for this MSCP.
|
||||||
* XXX MSCP inits here?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
error = bus_dmamap_create(dmat, UHA_MAXXFER, UHA_NSEG, UHA_MAXXFER,
|
||||||
0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
|
0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
|
||||||
&mscp->dmamap_xfer);
|
&mscp->dmamap_xfer);
|
||||||
if (error) {
|
if (error) {
|
||||||
printf("%s: can't create mscp dmamap_xfer\n",
|
printf("%s: can't create mscp DMA map, error = %d\n",
|
||||||
sc->sc_dev.dv_xname);
|
sc->sc_dev.dv_xname, error);
|
||||||
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);
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +334,8 @@ uha_init_mscp(sc, mscp)
|
||||||
* put in the phystokv hash table
|
* put in the phystokv hash table
|
||||||
* Never gets taken out.
|
* 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);
|
hashnum = MSCP_HASH(mscp->hashkey);
|
||||||
mscp->nexthash = sc->sc_mscphash[hashnum];
|
mscp->nexthash = sc->sc_mscphash[hashnum];
|
||||||
sc->sc_mscphash[hashnum] = mscp;
|
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.
|
* Create a set of MSCPs and add them to the free list.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
uha_create_mscps(sc, mem, size)
|
uha_create_mscps(sc, mscpstore, count)
|
||||||
struct uha_softc *sc;
|
struct uha_softc *sc;
|
||||||
void *mem;
|
struct uha_mscp *mscpstore;
|
||||||
size_t size;
|
int count;
|
||||||
{
|
{
|
||||||
bus_dma_segment_t seg;
|
|
||||||
struct uha_mscp *mscp;
|
struct uha_mscp *mscp;
|
||||||
int rseg, error;
|
int i, error;
|
||||||
|
|
||||||
if (sc->sc_nummscps >= UHA_MSCP_MAX)
|
bzero(mscpstore, sizeof(struct uha_mscp) * count);
|
||||||
return (0);
|
for (i = 0; i < count; i++) {
|
||||||
|
mscp = &mscpstore[i];
|
||||||
if ((mscp = mem) != NULL)
|
if ((error = uha_init_mscp(sc, mscp)) != 0) {
|
||||||
goto have_mem;
|
printf("%s: unable to initialize mscp, error = %d\n",
|
||||||
|
sc->sc_dev.dv_xname, error);
|
||||||
size = NBPG;
|
goto out;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_TAIL(&sc->sc_free_mscp, mscp, chain);
|
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++;
|
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
return (0);
|
return (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -400,20 +395,6 @@ uha_get_mscp(sc, flags)
|
||||||
TAILQ_REMOVE(&sc->sc_free_mscp, mscp, chain);
|
TAILQ_REMOVE(&sc->sc_free_mscp, mscp, chain);
|
||||||
break;
|
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)
|
if ((flags & SCSI_NOSLEEP) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
tsleep(&sc->sc_free_mscp, PRIBIO, "uhamsc", 0);
|
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"));
|
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
|
* If we were a data transfer, unload the map that described
|
||||||
* the data buffer.
|
* the data buffer.
|
||||||
|
@ -641,8 +626,8 @@ uha_scsi_cmd(xs)
|
||||||
mscp->target = sc_link->scsipi_scsi.target;
|
mscp->target = sc_link->scsipi_scsi.target;
|
||||||
mscp->lun = sc_link->scsipi_scsi.lun;
|
mscp->lun = sc_link->scsipi_scsi.lun;
|
||||||
mscp->scsi_cmd_length = xs->cmdlen;
|
mscp->scsi_cmd_length = xs->cmdlen;
|
||||||
mscp->sense_ptr = mscp->dmamap_self->dm_segs[0].ds_addr +
|
mscp->sense_ptr = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
|
||||||
offsetof(struct uha_mscp, mscp_sense);
|
UHA_MSCP_OFF(mscp) + offsetof(struct uha_mscp, mscp_sense);
|
||||||
mscp->req_sense_length = sizeof(mscp->mscp_sense);
|
mscp->req_sense_length = sizeof(mscp->mscp_sense);
|
||||||
mscp->host_stat = 0x00;
|
mscp->host_stat = 0x00;
|
||||||
mscp->target_stat = 0x00;
|
mscp->target_stat = 0x00;
|
||||||
|
@ -694,8 +679,8 @@ uha_scsi_cmd(xs)
|
||||||
mscp->dmamap_xfer->dm_segs[seg].ds_len;
|
mscp->dmamap_xfer->dm_segs[seg].ds_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
mscp->data_addr = mscp->dmamap_self->dm_segs[0].ds_addr +
|
mscp->data_addr = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
|
||||||
offsetof(struct uha_mscp, uha_dma);
|
UHA_MSCP_OFF(mscp) + offsetof(struct uha_mscp, uha_dma);
|
||||||
mscp->data_length = xs->datalen;
|
mscp->data_length = xs->datalen;
|
||||||
mscp->sgth = 0x01;
|
mscp->sgth = 0x01;
|
||||||
mscp->sg_num = seg;
|
mscp->sg_num = seg;
|
||||||
|
@ -708,6 +693,10 @@ uha_scsi_cmd(xs)
|
||||||
mscp->link_id = 0;
|
mscp->link_id = 0;
|
||||||
mscp->link_addr = (physaddr)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();
|
s = splbio();
|
||||||
(sc->start_mbox)(sc, mscp);
|
(sc->start_mbox)(sc, mscp);
|
||||||
splx(s);
|
splx(s);
|
||||||
|
|
|
@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
@ -264,17 +264,6 @@ struct uha_mscp {
|
||||||
#define MSCP_ABORT 0x02
|
#define MSCP_ABORT 0x02
|
||||||
int timeout;
|
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.
|
* This DMA map maps the buffer involved in the transfer.
|
||||||
* It's contents are loaded into "uha_dma" above.
|
* It's contents are loaded into "uha_dma" above.
|
||||||
|
|
|
@ -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.
|
* 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));
|
int (*poll) __P((struct uha_softc *, struct scsipi_xfer *, int));
|
||||||
void (*init) __P((struct uha_softc *));
|
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];
|
struct uha_mscp *sc_mscphash[MSCP_HASH_SIZE];
|
||||||
TAILQ_HEAD(, uha_mscp) sc_free_mscp;
|
TAILQ_HEAD(, uha_mscp) sc_free_mscp;
|
||||||
int sc_nummscps;
|
int sc_nummscps;
|
||||||
|
@ -59,6 +99,11 @@ struct uha_softc {
|
||||||
struct scsipi_xfer *sc_queuelast;
|
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 {
|
struct uha_probe_data {
|
||||||
int sc_irq, sc_drq;
|
int sc_irq, sc_drq;
|
||||||
int sc_scsi_dev;
|
int sc_scsi_dev;
|
||||||
|
|
|
@ -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.
|
* 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,
|
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)
|
if (mscp->flags & MSCP_ABORT)
|
||||||
bus_space_write_1(iot, ioh, U14_LINT, U14_ABORT);
|
bus_space_write_1(iot, ioh, U14_LINT, U14_ABORT);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue