Call siop_morecbd() only when scsipi ask us ADAPTER_REQ_GROW_RESOURCES.
This prevent using bus_dmamem_map() from interrupt context. Should fix kern/13827.
This commit is contained in:
parent
a84535fd3e
commit
ea29ee7d56
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: siop.c,v 1.46 2001/07/19 16:25:26 thorpej Exp $ */
|
/* $NetBSD: siop.c,v 1.47 2001/10/14 20:37:28 bouyer Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Manuel Bouyer.
|
* Copyright (c) 2000 Manuel Bouyer.
|
||||||
@ -88,7 +88,7 @@ int siop_scsicmd __P((struct scsipi_xfer *));
|
|||||||
void siop_scsipi_request __P((struct scsipi_channel *,
|
void siop_scsipi_request __P((struct scsipi_channel *,
|
||||||
scsipi_adapter_req_t, void *));
|
scsipi_adapter_req_t, void *));
|
||||||
void siop_dump_script __P((struct siop_softc *));
|
void siop_dump_script __P((struct siop_softc *));
|
||||||
int siop_morecbd __P((struct siop_softc *));
|
void siop_morecbd __P((struct siop_softc *));
|
||||||
struct siop_lunsw *siop_get_lunsw __P((struct siop_softc *));
|
struct siop_lunsw *siop_get_lunsw __P((struct siop_softc *));
|
||||||
void siop_add_reselsw __P((struct siop_softc *, int));
|
void siop_add_reselsw __P((struct siop_softc *, int));
|
||||||
void siop_update_scntl3 __P((struct siop_softc *, struct siop_target *));
|
void siop_update_scntl3 __P((struct siop_softc *, struct siop_target *));
|
||||||
@ -201,7 +201,7 @@ siop_attach(sc)
|
|||||||
|
|
||||||
sc->sc_adapt.adapt_dev = &sc->sc_dev;
|
sc->sc_adapt.adapt_dev = &sc->sc_dev;
|
||||||
sc->sc_adapt.adapt_nchannels = 1;
|
sc->sc_adapt.adapt_nchannels = 1;
|
||||||
sc->sc_adapt.adapt_openings = 225;
|
sc->sc_adapt.adapt_openings = 0;
|
||||||
sc->sc_adapt.adapt_max_periph = SIOP_NTAG - 1;
|
sc->sc_adapt.adapt_max_periph = SIOP_NTAG - 1;
|
||||||
sc->sc_adapt.adapt_ioctl = siop_ioctl;
|
sc->sc_adapt.adapt_ioctl = siop_ioctl;
|
||||||
sc->sc_adapt.adapt_minphys = minphys;
|
sc->sc_adapt.adapt_minphys = minphys;
|
||||||
@ -211,6 +211,7 @@ siop_attach(sc)
|
|||||||
sc->sc_chan.chan_adapter = &sc->sc_adapt;
|
sc->sc_chan.chan_adapter = &sc->sc_adapt;
|
||||||
sc->sc_chan.chan_bustype = &scsi_bustype;
|
sc->sc_chan.chan_bustype = &scsi_bustype;
|
||||||
sc->sc_chan.chan_channel = 0;
|
sc->sc_chan.chan_channel = 0;
|
||||||
|
sc->sc_chan.chan_flags = SCSIPI_CHAN_CANGROW;
|
||||||
sc->sc_chan.chan_ntargets = (sc->features & SF_BUS_WIDE) ? 16 : 8;
|
sc->sc_chan.chan_ntargets = (sc->features & SF_BUS_WIDE) ? 16 : 8;
|
||||||
sc->sc_chan.chan_nluns = 8;
|
sc->sc_chan.chan_nluns = 8;
|
||||||
sc->sc_chan.chan_id = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SCID);
|
sc->sc_chan.chan_id = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SCID);
|
||||||
@ -1190,24 +1191,13 @@ siop_scsipi_request(chan, req, arg)
|
|||||||
printf("starting cmd for %d:%d\n", target, lun);
|
printf("starting cmd for %d:%d\n", target, lun);
|
||||||
#endif
|
#endif
|
||||||
siop_cmd = TAILQ_FIRST(&sc->free_list);
|
siop_cmd = TAILQ_FIRST(&sc->free_list);
|
||||||
if (siop_cmd) {
|
|
||||||
TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
|
|
||||||
} else {
|
|
||||||
if (siop_morecbd(sc) == 0) {
|
|
||||||
siop_cmd = TAILQ_FIRST(&sc->free_list);
|
|
||||||
#ifdef DIAGNOSTIC
|
|
||||||
if (siop_cmd == NULL)
|
|
||||||
panic("siop_morecbd succeed and does nothing");
|
|
||||||
#endif
|
|
||||||
TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (siop_cmd == NULL) {
|
if (siop_cmd == NULL) {
|
||||||
xs->error = XS_RESOURCE_SHORTAGE;
|
xs->error = XS_RESOURCE_SHORTAGE;
|
||||||
scsipi_done(xs);
|
scsipi_done(xs);
|
||||||
splx(s);
|
splx(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if (siop_cmd->status != CMDST_FREE)
|
if (siop_cmd->status != CMDST_FREE)
|
||||||
panic("siop_scsicmd: new cmd not free");
|
panic("siop_scsicmd: new cmd not free");
|
||||||
@ -1316,7 +1306,11 @@ siop_scsipi_request(chan, req, arg)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case ADAPTER_REQ_GROW_RESOURCES:
|
case ADAPTER_REQ_GROW_RESOURCES:
|
||||||
/* XXX Not supported. */
|
#ifdef SIOP_DEBUG
|
||||||
|
printf("%s grow resources (%d)\n", sc->sc_dev.dv_xname,
|
||||||
|
sc->sc_adapt.adapt_openings);
|
||||||
|
#endif
|
||||||
|
siop_morecbd(sc);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ADAPTER_REQ_SET_XFER_MODE:
|
case ADAPTER_REQ_SET_XFER_MODE:
|
||||||
@ -1525,7 +1519,7 @@ siop_dump_script(sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
siop_morecbd(sc)
|
siop_morecbd(sc)
|
||||||
struct siop_softc *sc;
|
struct siop_softc *sc;
|
||||||
{
|
{
|
||||||
@ -1541,7 +1535,7 @@ siop_morecbd(sc)
|
|||||||
if (newcbd == NULL) {
|
if (newcbd == NULL) {
|
||||||
printf("%s: can't allocate memory for command descriptors "
|
printf("%s: can't allocate memory for command descriptors "
|
||||||
"head\n", sc->sc_dev.dv_xname);
|
"head\n", sc->sc_dev.dv_xname);
|
||||||
return ENOMEM;
|
return;
|
||||||
}
|
}
|
||||||
memset(newcbd, 0, sizeof(struct siop_cbd));
|
memset(newcbd, 0, sizeof(struct siop_cbd));
|
||||||
|
|
||||||
@ -1551,7 +1545,6 @@ siop_morecbd(sc)
|
|||||||
if (newcbd->cmds == NULL) {
|
if (newcbd->cmds == NULL) {
|
||||||
printf("%s: can't allocate memory for command descriptors\n",
|
printf("%s: can't allocate memory for command descriptors\n",
|
||||||
sc->sc_dev.dv_xname);
|
sc->sc_dev.dv_xname);
|
||||||
error = ENOMEM;
|
|
||||||
goto bad3;
|
goto bad3;
|
||||||
}
|
}
|
||||||
memset(newcbd->cmds, 0, sizeof(struct siop_cmd) * SIOP_NCMDPB);
|
memset(newcbd->cmds, 0, sizeof(struct siop_cmd) * SIOP_NCMDPB);
|
||||||
@ -1587,7 +1580,6 @@ siop_morecbd(sc)
|
|||||||
printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_dev.dv_xname,
|
printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_dev.dv_xname,
|
||||||
(unsigned long)newcbd->xferdma->dm_segs[0].ds_addr);
|
(unsigned long)newcbd->xferdma->dm_segs[0].ds_addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < SIOP_NCMDPB; i++) {
|
for (i = 0; i < SIOP_NCMDPB; i++) {
|
||||||
error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG,
|
error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG,
|
||||||
MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
|
MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
|
||||||
@ -1664,8 +1656,10 @@ siop_morecbd(sc)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_TAIL(&sc->cmds, newcbd, next);
|
TAILQ_INSERT_TAIL(&sc->cmds, newcbd, next);
|
||||||
return 0;
|
sc->sc_adapt.adapt_openings += SIOP_NCMDPB;
|
||||||
|
return;
|
||||||
bad0:
|
bad0:
|
||||||
|
bus_dmamap_unload(sc->sc_dmat, newcbd->xferdma);
|
||||||
bus_dmamap_destroy(sc->sc_dmat, newcbd->xferdma);
|
bus_dmamap_destroy(sc->sc_dmat, newcbd->xferdma);
|
||||||
bad1:
|
bad1:
|
||||||
bus_dmamem_free(sc->sc_dmat, &seg, rseg);
|
bus_dmamem_free(sc->sc_dmat, &seg, rseg);
|
||||||
@ -1673,7 +1667,7 @@ bad2:
|
|||||||
free(newcbd->cmds, M_DEVBUF);
|
free(newcbd->cmds, M_DEVBUF);
|
||||||
bad3:
|
bad3:
|
||||||
free(newcbd, M_DEVBUF);
|
free(newcbd, M_DEVBUF);
|
||||||
return error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct siop_lunsw *
|
struct siop_lunsw *
|
||||||
|
Loading…
Reference in New Issue
Block a user